activerecord-oracle_enhanced-adapter 1.4.3 → 5.2.0

Sign up to get free protection for your applications and to get access to all the features.
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