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,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record/connection_adapters/oracle_enhanced/database_tasks"
4
+ require "stringio"
5
+ require "tempfile"
6
+
7
+ describe "Oracle Enhanced adapter database tasks" do
8
+ include SchemaSpecHelper
9
+
10
+ let(:config) { CONNECTION_PARAMS.with_indifferent_access }
11
+
12
+ describe "create" do
13
+ let(:new_user_config) { config.merge(username: "oracle_enhanced_test_user") }
14
+ before do
15
+ fake_terminal(SYSTEM_CONNECTION_PARAMS[:password]) do
16
+ ActiveRecord::Tasks::DatabaseTasks.create(new_user_config)
17
+ end
18
+ end
19
+ it "creates user" do
20
+ query = "SELECT COUNT(*) FROM dba_users WHERE UPPER(username) = '#{new_user_config[:username].upcase}'"
21
+ expect(ActiveRecord::Base.connection.select_value(query)).to eq(1)
22
+ end
23
+ after do
24
+ ActiveRecord::Base.connection.execute("DROP USER #{new_user_config[:username]}")
25
+ end
26
+
27
+ def fake_terminal(input)
28
+ $stdin = StringIO.new
29
+ $stdout = StringIO.new
30
+ $stdin.puts(input)
31
+ $stdin.rewind
32
+ yield
33
+ ensure
34
+ $stdin = STDIN
35
+ $stdout = STDOUT
36
+ end
37
+ end
38
+
39
+ context "with test table" do
40
+ before(:all) do
41
+ $stdout, @original_stdout = StringIO.new, $stdout
42
+ $stderr, @original_stderr = StringIO.new, $stderr
43
+ end
44
+
45
+ after(:all) do
46
+ $stdout, $stderr = @original_stdout, @original_stderr
47
+ end
48
+
49
+ before do
50
+ ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
51
+ schema_define do
52
+ create_table :test_posts, force: true do |t|
53
+ t.string :name, limit: 20
54
+ end
55
+ end
56
+ end
57
+
58
+ describe "drop" do
59
+ before { ActiveRecord::Tasks::DatabaseTasks.drop(config) }
60
+ it "drops all tables" do
61
+ expect(ActiveRecord::Base.connection.table_exists?(:test_posts)).to be_falsey
62
+ end
63
+ end
64
+
65
+ describe "purge" do
66
+ before { ActiveRecord::Tasks::DatabaseTasks.purge(config) }
67
+ it "drops all tables" do
68
+ expect(ActiveRecord::Base.connection.table_exists?(:test_posts)).to be_falsey
69
+ expect(ActiveRecord::Base.connection.select_value("SELECT COUNT(*) FROM RECYCLEBIN")).to eq(0)
70
+ end
71
+ end
72
+
73
+ describe "structure" do
74
+ let(:temp_file) { Tempfile.create(["oracle_enhanced", ".sql"]).path }
75
+ before do
76
+ ActiveRecord::SchemaMigration.create_table
77
+ ActiveRecord::Base.connection.execute "INSERT INTO schema_migrations (version) VALUES ('20150101010000')"
78
+ end
79
+
80
+ describe "structure_dump" do
81
+ before { ActiveRecord::Tasks::DatabaseTasks.structure_dump(config, temp_file) }
82
+ it "dumps the database structure to a file without the schema information" do
83
+ contents = File.read(temp_file)
84
+ expect(contents).to include('CREATE TABLE "TEST_POSTS"')
85
+ expect(contents).not_to include("INSERT INTO schema_migrations")
86
+ end
87
+ end
88
+
89
+ describe "structure_load" do
90
+ before do
91
+ ActiveRecord::Tasks::DatabaseTasks.structure_dump(config, temp_file)
92
+ ActiveRecord::Tasks::DatabaseTasks.drop(config)
93
+ ActiveRecord::Tasks::DatabaseTasks.structure_load(config, temp_file)
94
+ end
95
+ it "loads the database structure from a file" do
96
+ expect(ActiveRecord::Base.connection.table_exists?(:test_posts)).to be_truthy
97
+ end
98
+ end
99
+
100
+ after do
101
+ File.unlink(temp_file)
102
+ ActiveRecord::SchemaMigration.drop_table
103
+ end
104
+ end
105
+
106
+ after do
107
+ schema_define do
108
+ drop_table :test_posts, if_exists: true
109
+ end
110
+ end
111
+ end
112
+ end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
2
 
3
3
  describe "OracleEnhancedAdapter logging dbms_output from plsql" do
4
4
  include LoggerSpecHelper
@@ -42,28 +42,28 @@ describe "OracleEnhancedAdapter logging dbms_output from plsql" do
42
42
  it "should NOT log dbms output when dbms output is disabled" do
43
43
  @conn.disable_dbms_output
44
44
 
45
- @conn.select_all("select more_than_five_characters_long('hi there') is_it_long from dual").should == [{'is_it_long'=>1}]
45
+ expect(@conn.select_all("select more_than_five_characters_long('hi there') is_it_long from dual").to_a).to eq([{ "is_it_long" => 1 }])
46
46
 
47
- @logger.output(:debug).should_not match(/^DBMS_OUTPUT/)
47
+ expect(@logger.output(:debug)).not_to match(/^DBMS_OUTPUT/)
48
48
  end
49
49
 
50
50
  it "should log dbms output lines to the rails log" do
51
51
  @conn.enable_dbms_output
52
52
 
53
- @conn.select_all("select more_than_five_characters_long('hi there') is_it_long from dual").should == [{'is_it_long'=>1}]
54
-
55
- @logger.output(:debug).should match(/^DBMS_OUTPUT: before the if -hi there-$/)
56
- @logger.output(:debug).should match(/^DBMS_OUTPUT: it is longer than 5$/)
57
- @logger.output(:debug).should match(/^DBMS_OUTPUT: about to return: 1$/)
53
+ expect(@conn.select_all("select more_than_five_characters_long('hi there') is_it_long from dual").to_a).to eq([{ "is_it_long" => 1 }])
54
+
55
+ expect(@logger.output(:debug)).to match(/^DBMS_OUTPUT: before the if -hi there-$/)
56
+ expect(@logger.output(:debug)).to match(/^DBMS_OUTPUT: it is longer than 5$/)
57
+ expect(@logger.output(:debug)).to match(/^DBMS_OUTPUT: about to return: 1$/)
58
58
  end
59
59
 
60
60
  it "should log dbms output lines to the rails log" do
61
61
  @conn.enable_dbms_output
62
62
 
63
- @conn.select_all("select more_than_five_characters_long('short') is_it_long from dual").should == [{'is_it_long'=>0}]
64
-
65
- @logger.output(:debug).should match(/^DBMS_OUTPUT: before the if -short-$/)
66
- @logger.output(:debug).should match(/^DBMS_OUTPUT: it is 5 or shorter$/)
67
- @logger.output(:debug).should match(/^DBMS_OUTPUT: about to return: 0$/)
63
+ expect(@conn.select_all("select more_than_five_characters_long('short') is_it_long from dual").to_a).to eq([{ "is_it_long" => 0 }])
64
+
65
+ expect(@logger.output(:debug)).to match(/^DBMS_OUTPUT: before the if -short-$/)
66
+ expect(@logger.output(:debug)).to match(/^DBMS_OUTPUT: it is 5 or shorter$/)
67
+ expect(@logger.output(:debug)).to match(/^DBMS_OUTPUT: about to return: 0$/)
68
68
  end
69
69
  end
@@ -0,0 +1,365 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ruby-plsql"
4
+
5
+ describe "OracleEnhancedAdapter custom methods for create, update and destroy" do
6
+ include LoggerSpecHelper
7
+ include SchemaSpecHelper
8
+
9
+ before(:all) do
10
+ ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
11
+ @conn = ActiveRecord::Base.connection
12
+ plsql.activerecord_class = ActiveRecord::Base
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
26
+ @conn.execute <<-SQL
27
+ CREATE OR REPLACE PACKAGE test_employees_pkg IS
28
+ PROCEDURE create_employee(
29
+ p_first_name VARCHAR2,
30
+ p_last_name VARCHAR2,
31
+ p_hire_date DATE,
32
+ p_salary NUMBER,
33
+ p_description VARCHAR2,
34
+ p_employee_id OUT NUMBER);
35
+ PROCEDURE update_employee(
36
+ p_employee_id NUMBER,
37
+ p_first_name VARCHAR2,
38
+ p_last_name VARCHAR2,
39
+ p_hire_date DATE,
40
+ p_salary NUMBER,
41
+ p_description VARCHAR2);
42
+ PROCEDURE delete_employee(
43
+ p_employee_id NUMBER);
44
+ END;
45
+ SQL
46
+ @conn.execute <<-SQL
47
+ CREATE OR REPLACE PACKAGE BODY test_employees_pkg IS
48
+ PROCEDURE create_employee(
49
+ p_first_name VARCHAR2,
50
+ p_last_name VARCHAR2,
51
+ p_hire_date DATE,
52
+ p_salary NUMBER,
53
+ p_description VARCHAR2,
54
+ p_employee_id OUT NUMBER)
55
+ IS
56
+ BEGIN
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,
59
+ version, create_time, update_time)
60
+ VALUES (p_employee_id, p_first_name, p_last_name, p_hire_date, p_salary, p_description,
61
+ 1, SYSDATE, SYSDATE);
62
+ END create_employee;
63
+
64
+ PROCEDURE update_employee(
65
+ p_employee_id NUMBER,
66
+ p_first_name VARCHAR2,
67
+ p_last_name VARCHAR2,
68
+ p_hire_date DATE,
69
+ p_salary NUMBER,
70
+ p_description VARCHAR2)
71
+ IS
72
+ v_version NUMBER;
73
+ BEGIN
74
+ SELECT version INTO v_version FROM test_employees WHERE id = p_employee_id FOR UPDATE;
75
+ UPDATE test_employees
76
+ SET first_name = p_first_name, last_name = p_last_name,
77
+ hire_date = p_hire_date, salary = p_salary, description = p_description,
78
+ version = v_version + 1, update_time = SYSDATE
79
+ WHERE id = p_employee_id;
80
+ END update_employee;
81
+
82
+ PROCEDURE delete_employee(
83
+ p_employee_id NUMBER)
84
+ IS
85
+ BEGIN
86
+ DELETE FROM test_employees WHERE id = p_employee_id;
87
+ END delete_employee;
88
+ END;
89
+ SQL
90
+
91
+ end
92
+
93
+ after(:all) do
94
+ @conn = ActiveRecord::Base.connection
95
+ @conn.drop_table :test_employees, if_exists: true
96
+ @conn.execute "DROP PACKAGE test_employees_pkg"
97
+ end
98
+
99
+ before(:each) do
100
+ class ::TestEmployee < ActiveRecord::Base
101
+ include ActiveRecord::OracleEnhancedProcedures
102
+
103
+ validates_presence_of :first_name, :last_name, :hire_date
104
+
105
+ # should return ID of new record
106
+ set_create_method do
107
+ plsql.test_employees_pkg.create_employee(
108
+ p_first_name: first_name,
109
+ p_last_name: last_name,
110
+ p_hire_date: hire_date,
111
+ p_salary: salary,
112
+ p_description: "#{first_name} #{last_name}",
113
+ p_employee_id: nil
114
+ )[:p_employee_id]
115
+ end
116
+
117
+ # return value is ignored
118
+ set_update_method do
119
+ plsql.test_employees_pkg.update_employee(
120
+ p_employee_id: id,
121
+ p_first_name: first_name,
122
+ p_last_name: last_name,
123
+ p_hire_date: hire_date,
124
+ p_salary: salary,
125
+ p_description: "#{first_name} #{last_name}"
126
+ )
127
+ end
128
+
129
+ # return value is ignored
130
+ set_delete_method do
131
+ plsql.test_employees_pkg.delete_employee(
132
+ p_employee_id: id
133
+ )
134
+ end
135
+
136
+ private
137
+
138
+ def raise_make_transaction_rollback
139
+ raise "Make the transaction rollback"
140
+ end
141
+ end
142
+
143
+ @today = Date.new(2008, 6, 28)
144
+ @buffer = StringIO.new
145
+ end
146
+
147
+ after(:each) do
148
+ Object.send(:remove_const, "TestEmployee")
149
+ ActiveRecord::Base.clear_cache!
150
+ end
151
+
152
+ it "should create record" do
153
+ @employee = TestEmployee.create(
154
+ first_name: "First",
155
+ last_name: "Last",
156
+ hire_date: @today
157
+ )
158
+ @employee.reload
159
+ expect(@employee.first_name).to eq("First")
160
+ expect(@employee.last_name).to eq("Last")
161
+ expect(@employee.hire_date).to eq(@today)
162
+ expect(@employee.description).to eq("First Last")
163
+ expect(@employee.create_time).not_to be_nil
164
+ expect(@employee.update_time).not_to be_nil
165
+ end
166
+
167
+ it "should rollback record when exception is raised in after_create callback" do
168
+ TestEmployee.after_create :raise_make_transaction_rollback
169
+
170
+ @employee = TestEmployee.new(
171
+ first_name: "First",
172
+ last_name: "Last",
173
+ hire_date: @today
174
+ )
175
+ employees_count = TestEmployee.count
176
+ expect {
177
+ @employee.save
178
+ }.to raise_error("Make the transaction rollback")
179
+ expect(@employee.new_record?).to be_truthy
180
+ expect(TestEmployee.count).to eq(employees_count)
181
+ end
182
+
183
+ it "should update record" do
184
+ @employee = TestEmployee.create(
185
+ first_name: "First",
186
+ last_name: "Last",
187
+ hire_date: @today,
188
+ description: "description"
189
+ )
190
+ @employee.reload
191
+ @employee.first_name = "Second"
192
+ @employee.save!
193
+ @employee.reload
194
+ expect(@employee.description).to eq("Second Last")
195
+ end
196
+
197
+ it "should rollback record when exception is raised in after_update callback" do
198
+ TestEmployee.after_update :raise_make_transaction_rollback
199
+
200
+ @employee = TestEmployee.create(
201
+ first_name: "First",
202
+ last_name: "Last",
203
+ hire_date: @today,
204
+ description: "description"
205
+ )
206
+ @employee.reload
207
+ @employee.first_name = "Second"
208
+ expect {
209
+ @employee.save
210
+ }.to raise_error("Make the transaction rollback")
211
+ @employee.reload
212
+ expect(@employee.first_name).to eq("First")
213
+ end
214
+
215
+ it "should not update record if nothing is changed and partial writes are enabled" do
216
+ TestEmployee.partial_writes = true
217
+ @employee = TestEmployee.create(
218
+ first_name: "First",
219
+ last_name: "Last",
220
+ hire_date: @today
221
+ )
222
+ @employee.reload
223
+ @employee.save!
224
+ @employee.reload
225
+ expect(@employee.version).to eq(1)
226
+ end
227
+
228
+ it "should update record if nothing is changed and partial writes are disabled" do
229
+ TestEmployee.partial_writes = false
230
+ @employee = TestEmployee.create(
231
+ first_name: "First",
232
+ last_name: "Last",
233
+ hire_date: @today
234
+ )
235
+ @employee.reload
236
+ @employee.save!
237
+ @employee.reload
238
+ expect(@employee.version).to eq(2)
239
+ end
240
+
241
+ it "should delete record" do
242
+ @employee = TestEmployee.create(
243
+ first_name: "First",
244
+ last_name: "Last",
245
+ hire_date: @today
246
+ )
247
+ @employee.reload
248
+ empl_id = @employee.id
249
+ @employee.destroy
250
+ expect(@employee).to be_frozen
251
+ expect(TestEmployee.find_by_id(empl_id)).to be_nil
252
+ end
253
+
254
+ it "should delete record and set destroyed flag" do
255
+ @employee = TestEmployee.create(
256
+ first_name: "First",
257
+ last_name: "Last",
258
+ hire_date: @today
259
+ )
260
+ @employee.reload
261
+ @employee.destroy
262
+ expect(@employee).to be_destroyed
263
+ end
264
+
265
+ it "should rollback record when exception is raised in after_destroy callback" do
266
+ set_logger
267
+ TestEmployee.after_destroy :raise_make_transaction_rollback
268
+
269
+ @employee = TestEmployee.create(
270
+ first_name: "First",
271
+ last_name: "Last",
272
+ hire_date: @today
273
+ )
274
+ @employee.reload
275
+ empl_id = @employee.id
276
+ expect {
277
+ @employee.destroy
278
+ }.to raise_error("Make the transaction rollback")
279
+ expect(@employee.id).to eq(empl_id)
280
+ expect(TestEmployee.find_by_id(empl_id)).not_to be_nil
281
+ clear_logger
282
+ end
283
+
284
+ it "should set timestamps when creating record" do
285
+ @employee = TestEmployee.create(
286
+ first_name: "First",
287
+ last_name: "Last",
288
+ hire_date: @today
289
+ )
290
+ expect(@employee.created_at).not_to be_nil
291
+ expect(@employee.updated_at).not_to be_nil
292
+ end
293
+
294
+ it "should set timestamps when updating record" do
295
+ @employee = TestEmployee.create(
296
+ first_name: "First",
297
+ last_name: "Last",
298
+ hire_date: @today
299
+ )
300
+ @employee.reload
301
+ expect(@employee.created_at).to be_nil
302
+ expect(@employee.updated_at).to be_nil
303
+ @employee.first_name = "Second"
304
+ @employee.save!
305
+ expect(@employee.created_at).to be_nil
306
+ expect(@employee.updated_at).not_to be_nil
307
+ end
308
+
309
+ it "should log create record" do
310
+ set_logger
311
+ @employee = TestEmployee.create(
312
+ first_name: "First",
313
+ last_name: "Last",
314
+ hire_date: @today
315
+ )
316
+ expect(@logger.logged(:debug).last).to match(/^TestEmployee Create \(\d+\.\d+(ms)?\) custom create method$/)
317
+ clear_logger
318
+ end
319
+
320
+ it "should log update record" do
321
+ (TestEmployee.partial_writes = false) rescue nil
322
+ @employee = TestEmployee.create(
323
+ first_name: "First",
324
+ last_name: "Last",
325
+ hire_date: @today
326
+ )
327
+ set_logger
328
+ @employee.save!
329
+ expect(@logger.logged(:debug).last).to match(/^TestEmployee Update \(\d+\.\d+(ms)?\) custom update method with id=#{@employee.id}$/)
330
+ clear_logger
331
+ end
332
+
333
+ it "should log delete record" do
334
+ @employee = TestEmployee.create(
335
+ first_name: "First",
336
+ last_name: "Last",
337
+ hire_date: @today
338
+ )
339
+ set_logger
340
+ @employee.destroy
341
+ expect(@logger.logged(:debug).last).to match(/^TestEmployee Destroy \(\d+\.\d+(ms)?\) custom delete method with id=#{@employee.id}$/)
342
+ clear_logger
343
+ end
344
+
345
+ it "should validate new record before creation" do
346
+ @employee = TestEmployee.new(
347
+ last_name: "Last",
348
+ hire_date: @today
349
+ )
350
+ expect(@employee.save).to be_falsey
351
+ expect(@employee.errors[:first_name]).not_to be_blank
352
+ end
353
+
354
+ it "should validate existing record before update" do
355
+ @employee = TestEmployee.create(
356
+ first_name: "First",
357
+ last_name: "Last",
358
+ hire_date: @today
359
+ )
360
+ @employee.first_name = nil
361
+ expect(@employee.save).to be_falsey
362
+ expect(@employee.errors[:first_name]).not_to be_blank
363
+ end
364
+
365
+ end