pmacs-activerecord-oracle_enhanced-adapter 1.4.2.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.rspec +2 -0
  2. data/Gemfile +52 -0
  3. data/History.md +284 -0
  4. data/License.txt +20 -0
  5. data/README.md +403 -0
  6. data/RUNNING_TESTS.md +45 -0
  7. data/Rakefile +59 -0
  8. data/VERSION +1 -0
  9. data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +5 -0
  10. data/lib/active_record/connection_adapters/oracle_enhanced.rake +105 -0
  11. data/lib/active_record/connection_adapters/oracle_enhanced_activerecord_patches.rb +41 -0
  12. data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +1408 -0
  13. data/lib/active_record/connection_adapters/oracle_enhanced_base_ext.rb +118 -0
  14. data/lib/active_record/connection_adapters/oracle_enhanced_column.rb +141 -0
  15. data/lib/active_record/connection_adapters/oracle_enhanced_connection.rb +135 -0
  16. data/lib/active_record/connection_adapters/oracle_enhanced_context_index.rb +359 -0
  17. data/lib/active_record/connection_adapters/oracle_enhanced_core_ext.rb +25 -0
  18. data/lib/active_record/connection_adapters/oracle_enhanced_cpk.rb +21 -0
  19. data/lib/active_record/connection_adapters/oracle_enhanced_dirty.rb +44 -0
  20. data/lib/active_record/connection_adapters/oracle_enhanced_jdbc_connection.rb +565 -0
  21. data/lib/active_record/connection_adapters/oracle_enhanced_oci_connection.rb +491 -0
  22. data/lib/active_record/connection_adapters/oracle_enhanced_procedures.rb +260 -0
  23. data/lib/active_record/connection_adapters/oracle_enhanced_schema_definitions.rb +231 -0
  24. data/lib/active_record/connection_adapters/oracle_enhanced_schema_dumper.rb +257 -0
  25. data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb +397 -0
  26. data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements_ext.rb +265 -0
  27. data/lib/active_record/connection_adapters/oracle_enhanced_structure_dump.rb +294 -0
  28. data/lib/active_record/connection_adapters/oracle_enhanced_tasks.rb +17 -0
  29. data/lib/active_record/connection_adapters/oracle_enhanced_version.rb +1 -0
  30. data/lib/pmacs-activerecord-oracle_enhanced-adapter.rb +25 -0
  31. data/pmacs-activerecord-oracle_enhanced-adapter.gemspec +131 -0
  32. data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +778 -0
  33. data/spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb +332 -0
  34. data/spec/active_record/connection_adapters/oracle_enhanced_context_index_spec.rb +427 -0
  35. data/spec/active_record/connection_adapters/oracle_enhanced_core_ext_spec.rb +19 -0
  36. data/spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb +113 -0
  37. data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +1376 -0
  38. data/spec/active_record/connection_adapters/oracle_enhanced_dbms_output_spec.rb +69 -0
  39. data/spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb +141 -0
  40. data/spec/active_record/connection_adapters/oracle_enhanced_emulate_oracle_adapter_spec.rb +25 -0
  41. data/spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb +378 -0
  42. data/spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb +438 -0
  43. data/spec/active_record/connection_adapters/oracle_enhanced_schema_statements_spec.rb +1280 -0
  44. data/spec/active_record/connection_adapters/oracle_enhanced_structure_dump_spec.rb +339 -0
  45. data/spec/spec_helper.rb +187 -0
  46. metadata +302 -0
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe "OracleEnhancedAdapter logging dbms_output from plsql" do
4
+ include LoggerSpecHelper
5
+
6
+ before(:all) do
7
+ ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
8
+ ActiveRecord::Base.connection.execute <<-SQL
9
+ CREATE or REPLACE
10
+ FUNCTION MORE_THAN_FIVE_CHARACTERS_LONG (some_text VARCHAR2) RETURN INTEGER
11
+ AS
12
+ longer_than_five INTEGER;
13
+ BEGIN
14
+ dbms_output.put_line('before the if -' || some_text || '-');
15
+ IF length(some_text) > 5 THEN
16
+ dbms_output.put_line('it is longer than 5');
17
+ longer_than_five := 1;
18
+ ELSE
19
+ dbms_output.put_line('it is 5 or shorter');
20
+ longer_than_five := 0;
21
+ END IF;
22
+ dbms_output.put_line('about to return: ' || longer_than_five);
23
+ RETURN longer_than_five;
24
+ END;
25
+ SQL
26
+ end
27
+
28
+ after(:all) do
29
+ ActiveRecord::Base.connection.execute "DROP FUNCTION MORE_THAN_FIVE_CHARACTERS_LONG"
30
+ end
31
+
32
+ before(:each) do
33
+ set_logger
34
+ ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
35
+ @conn = ActiveRecord::Base.connection
36
+ end
37
+
38
+ after(:each) do
39
+ clear_logger
40
+ end
41
+
42
+ it "should NOT log dbms output when dbms output is disabled" do
43
+ @conn.disable_dbms_output
44
+
45
+ @conn.select_all("select more_than_five_characters_long('hi there') is_it_long from dual").should == [{'is_it_long'=>1}]
46
+
47
+ @logger.output(:debug).should_not match(/^DBMS_OUTPUT/)
48
+ end
49
+
50
+ it "should log dbms output lines to the rails log" do
51
+ @conn.enable_dbms_output
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$/)
58
+ end
59
+
60
+ it "should log dbms output lines to the rails log" do
61
+ @conn.enable_dbms_output
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$/)
68
+ end
69
+ end
@@ -0,0 +1,141 @@
1
+ require 'spec_helper'
2
+
3
+ if ActiveRecord::Base.method_defined?(:changed?)
4
+
5
+ describe "OracleEnhancedAdapter dirty object tracking" do
6
+
7
+ before(:all) do
8
+ ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
9
+ @conn = ActiveRecord::Base.connection
10
+ @conn.execute "DROP TABLE test_employees" rescue nil
11
+ @conn.execute "DROP SEQUENCE test_employees_seq" rescue nil
12
+ @conn.execute <<-SQL
13
+ CREATE TABLE test_employees (
14
+ id NUMBER PRIMARY KEY,
15
+ first_name VARCHAR2(20),
16
+ last_name VARCHAR2(25),
17
+ job_id NUMBER(6,0) NULL,
18
+ salary NUMBER(8,2),
19
+ comments CLOB,
20
+ hire_date DATE
21
+ )
22
+ SQL
23
+ @conn.execute <<-SQL
24
+ CREATE SEQUENCE test_employees_seq MINVALUE 1
25
+ INCREMENT BY 1 CACHE 20 NOORDER NOCYCLE
26
+ SQL
27
+ class TestEmployee < ActiveRecord::Base
28
+ end
29
+ end
30
+
31
+ after(:all) do
32
+ Object.send(:remove_const, "TestEmployee")
33
+ @conn.execute "DROP TABLE test_employees"
34
+ @conn.execute "DROP SEQUENCE test_employees_seq"
35
+ ActiveRecord::Base.clear_cache! if ActiveRecord::Base.respond_to?(:"clear_cache!")
36
+ end
37
+
38
+ it "should not mark empty string (stored as NULL) as changed when reassigning it" do
39
+ @employee = TestEmployee.create!(:first_name => '')
40
+ @employee.first_name = ''
41
+ @employee.should_not be_changed
42
+ @employee.reload
43
+ @employee.first_name = ''
44
+ @employee.should_not be_changed
45
+ end
46
+
47
+ it "should not mark empty integer (stored as NULL) as changed when reassigning it" do
48
+ @employee = TestEmployee.create!(:job_id => '')
49
+ @employee.job_id = ''
50
+ @employee.should_not be_changed
51
+ @employee.reload
52
+ @employee.job_id = ''
53
+ @employee.should_not be_changed
54
+ end
55
+
56
+ it "should not mark empty decimal (stored as NULL) as changed when reassigning it" do
57
+ @employee = TestEmployee.create!(:salary => '')
58
+ @employee.salary = ''
59
+ @employee.should_not be_changed
60
+ @employee.reload
61
+ @employee.salary = ''
62
+ @employee.should_not be_changed
63
+ end
64
+
65
+ it "should not mark empty text (stored as NULL) as changed when reassigning it" do
66
+ @employee = TestEmployee.create!(:comments => nil)
67
+ @employee.comments = nil
68
+ @employee.should_not be_changed
69
+ @employee.reload
70
+ @employee.comments = nil
71
+ @employee.should_not be_changed
72
+ end
73
+
74
+ it "should not mark empty text (stored as empty_clob()) as changed when reassigning it" do
75
+ @employee = TestEmployee.create!(:comments => '')
76
+ @employee.comments = ''
77
+ @employee.should_not be_changed
78
+ @employee.reload
79
+ @employee.comments = ''
80
+ @employee.should_not be_changed
81
+ end
82
+
83
+ it "should mark empty text (stored as empty_clob()) as changed when assigning nil to it" do
84
+ @employee = TestEmployee.create!(:comments => '')
85
+ @employee.comments = nil
86
+ @employee.should be_changed
87
+ @employee.reload
88
+ @employee.comments = nil
89
+ @employee.should be_changed
90
+ end
91
+
92
+ it "should mark empty text (stored as NULL) as changed when assigning '' to it" do
93
+ @employee = TestEmployee.create!(:comments => nil)
94
+ @employee.comments = ''
95
+ @employee.should be_changed
96
+ @employee.reload
97
+ @employee.comments = ''
98
+ @employee.should be_changed
99
+ end
100
+
101
+ it "should not mark empty date (stored as NULL) as changed when reassigning it" do
102
+ @employee = TestEmployee.create!(:hire_date => '')
103
+ @employee.hire_date = ''
104
+ @employee.should_not be_changed
105
+ @employee.reload
106
+ @employee.hire_date = ''
107
+ @employee.should_not be_changed
108
+ end
109
+
110
+ it "should not mark integer as changed when reassigning it" do
111
+ @employee = TestEmployee.new
112
+ @employee.job_id = 0
113
+ @employee.save!.should be_true
114
+
115
+ @employee.should_not be_changed
116
+
117
+ @employee.job_id = '0'
118
+ @employee.should_not be_changed
119
+ end
120
+
121
+ it "should not update unchanged CLOBs" do
122
+ @employee = TestEmployee.create!(
123
+ :comments => "initial"
124
+ )
125
+ @employee.save!.should be_true
126
+ @employee.reload
127
+ @employee.comments.should == 'initial'
128
+
129
+ oci_conn = @conn.instance_variable_get('@connection')
130
+ class << oci_conn
131
+ def write_lob(lob, value, is_binary = false); raise "don't do this'"; end
132
+ end
133
+ @employee.save!.should_not raise_exception(RuntimeError, "don't do this'")
134
+ class << oci_conn
135
+ remove_method :write_lob
136
+ end
137
+ end
138
+
139
+ end
140
+
141
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe "OracleEnhancedAdapter emulate OracleAdapter" do
4
+
5
+ before(:all) do
6
+ if defined?(ActiveRecord::ConnectionAdapters::OracleAdapter)
7
+ @old_oracle_adapter = ActiveRecord::ConnectionAdapters::OracleAdapter
8
+ ActiveRecord::ConnectionAdapters.send(:remove_const, :OracleAdapter)
9
+ end
10
+ end
11
+
12
+ it "should be an OracleAdapter" do
13
+ @conn = ActiveRecord::Base.establish_connection(CONNECTION_PARAMS.merge(:emulate_oracle_adapter => true))
14
+ ActiveRecord::Base.connection.should_not be_nil
15
+ ActiveRecord::Base.connection.is_a?(ActiveRecord::ConnectionAdapters::OracleAdapter).should be_true
16
+ end
17
+
18
+ after(:all) do
19
+ if @old_oracle_adapter
20
+ ActiveRecord::ConnectionAdapters.send(:remove_const, :OracleAdapter)
21
+ ActiveRecord::ConnectionAdapters::OracleAdapter = @old_oracle_adapter
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,378 @@
1
+ require 'spec_helper'
2
+
3
+ require 'ruby-plsql'
4
+
5
+ describe "OracleEnhancedAdapter custom methods for create, update and destroy" do
6
+ include LoggerSpecHelper
7
+
8
+ before(:all) do
9
+ ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
10
+ @conn = ActiveRecord::Base.connection
11
+ plsql.activerecord_class = ActiveRecord::Base
12
+ @conn.execute("DROP TABLE test_employees") rescue nil
13
+ @conn.execute <<-SQL
14
+ CREATE TABLE test_employees (
15
+ employee_id NUMBER(6,0) PRIMARY KEY,
16
+ first_name VARCHAR2(20),
17
+ last_name VARCHAR2(25),
18
+ hire_date DATE,
19
+ salary NUMBER(8,2),
20
+ description CLOB,
21
+ version NUMBER(15,0),
22
+ create_time DATE,
23
+ update_time DATE,
24
+ created_at DATE,
25
+ updated_at DATE
26
+ )
27
+ SQL
28
+ @conn.execute("DROP SEQUENCE test_employees_s") rescue nil
29
+ @conn.execute <<-SQL
30
+ CREATE SEQUENCE test_employees_s MINVALUE 1
31
+ INCREMENT BY 1 CACHE 20 NOORDER NOCYCLE
32
+ SQL
33
+ @conn.execute <<-SQL
34
+ CREATE OR REPLACE PACKAGE test_employees_pkg IS
35
+ PROCEDURE create_employee(
36
+ p_first_name VARCHAR2,
37
+ p_last_name VARCHAR2,
38
+ p_hire_date DATE,
39
+ p_salary NUMBER,
40
+ p_description VARCHAR2,
41
+ p_employee_id OUT NUMBER);
42
+ PROCEDURE update_employee(
43
+ p_employee_id NUMBER,
44
+ p_first_name VARCHAR2,
45
+ p_last_name VARCHAR2,
46
+ p_hire_date DATE,
47
+ p_salary NUMBER,
48
+ p_description VARCHAR2);
49
+ PROCEDURE delete_employee(
50
+ p_employee_id NUMBER);
51
+ END;
52
+ SQL
53
+ @conn.execute <<-SQL
54
+ CREATE OR REPLACE PACKAGE BODY test_employees_pkg IS
55
+ PROCEDURE create_employee(
56
+ p_first_name VARCHAR2,
57
+ p_last_name VARCHAR2,
58
+ p_hire_date DATE,
59
+ p_salary NUMBER,
60
+ p_description VARCHAR2,
61
+ p_employee_id OUT NUMBER)
62
+ IS
63
+ BEGIN
64
+ SELECT test_employees_s.NEXTVAL INTO p_employee_id FROM dual;
65
+ INSERT INTO test_employees (employee_id, first_name, last_name, hire_date, salary, description,
66
+ version, create_time, update_time)
67
+ VALUES (p_employee_id, p_first_name, p_last_name, p_hire_date, p_salary, p_description,
68
+ 1, SYSDATE, SYSDATE);
69
+ END create_employee;
70
+
71
+ PROCEDURE update_employee(
72
+ p_employee_id NUMBER,
73
+ p_first_name VARCHAR2,
74
+ p_last_name VARCHAR2,
75
+ p_hire_date DATE,
76
+ p_salary NUMBER,
77
+ p_description VARCHAR2)
78
+ IS
79
+ v_version NUMBER;
80
+ BEGIN
81
+ SELECT version INTO v_version FROM test_employees WHERE employee_id = p_employee_id FOR UPDATE;
82
+ UPDATE test_employees
83
+ SET first_name = p_first_name, last_name = p_last_name,
84
+ hire_date = p_hire_date, salary = p_salary, description = p_description,
85
+ version = v_version + 1, update_time = SYSDATE
86
+ WHERE employee_id = p_employee_id;
87
+ END update_employee;
88
+
89
+ PROCEDURE delete_employee(
90
+ p_employee_id NUMBER)
91
+ IS
92
+ BEGIN
93
+ DELETE FROM test_employees WHERE employee_id = p_employee_id;
94
+ END delete_employee;
95
+ END;
96
+ SQL
97
+
98
+ ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
99
+ end
100
+
101
+ after(:all) do
102
+ @conn = ActiveRecord::Base.connection
103
+ @conn.execute "DROP TABLE test_employees"
104
+ @conn.execute "DROP SEQUENCE test_employees_s"
105
+ @conn.execute "DROP PACKAGE test_employees_pkg"
106
+ end
107
+
108
+ before(:each) do
109
+ class ::TestEmployee < ActiveRecord::Base
110
+ if self.respond_to?(:primary_key=)
111
+ self.primary_key = :employee_id
112
+ else
113
+ set_primary_key :employee_id
114
+ end
115
+
116
+ validates_presence_of :first_name, :last_name, :hire_date
117
+
118
+ # should return ID of new record
119
+ set_create_method do
120
+ plsql.test_employees_pkg.create_employee(
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
+ :p_employee_id => nil
127
+ )[:p_employee_id]
128
+ end
129
+
130
+ # return value is ignored
131
+ set_update_method do
132
+ plsql.test_employees_pkg.update_employee(
133
+ :p_employee_id => id,
134
+ :p_first_name => first_name,
135
+ :p_last_name => last_name,
136
+ :p_hire_date => hire_date,
137
+ :p_salary => salary,
138
+ :p_description => "#{first_name} #{last_name}"
139
+ )
140
+ end
141
+
142
+ # return value is ignored
143
+ set_delete_method do
144
+ plsql.test_employees_pkg.delete_employee(
145
+ :p_employee_id => id
146
+ )
147
+ end
148
+
149
+ private
150
+
151
+ def raise_make_transaction_rollback
152
+ raise "Make the transaction rollback"
153
+ end
154
+ end
155
+
156
+ @today = Date.new(2008,6,28)
157
+ @buffer = StringIO.new
158
+ end
159
+
160
+ after(:each) do
161
+ Object.send(:remove_const, "TestEmployee")
162
+ ActiveRecord::Base.clear_cache! if ActiveRecord::Base.respond_to?(:"clear_cache!")
163
+ end
164
+
165
+ it "should create record" do
166
+ @employee = TestEmployee.create(
167
+ :first_name => "First",
168
+ :last_name => "Last",
169
+ :hire_date => @today
170
+ )
171
+ @employee.reload
172
+ @employee.first_name.should == "First"
173
+ @employee.last_name.should == "Last"
174
+ @employee.hire_date.should == @today
175
+ @employee.description.should == "First Last"
176
+ @employee.create_time.should_not be_nil
177
+ @employee.update_time.should_not be_nil
178
+ end
179
+
180
+ it "should rollback record when exception is raised in after_create callback" do
181
+ TestEmployee.after_create :raise_make_transaction_rollback
182
+
183
+ @employee = TestEmployee.new(
184
+ :first_name => "First",
185
+ :last_name => "Last",
186
+ :hire_date => @today
187
+ )
188
+ employees_count = TestEmployee.count
189
+ lambda {
190
+ @employee.save
191
+ }.should raise_error("Make the transaction rollback")
192
+ @employee.id.should == nil
193
+ TestEmployee.count.should == employees_count
194
+ end
195
+
196
+ it "should update record" do
197
+ @employee = TestEmployee.create(
198
+ :first_name => "First",
199
+ :last_name => "Last",
200
+ :hire_date => @today,
201
+ :description => "description"
202
+ )
203
+ @employee.reload
204
+ @employee.first_name = "Second"
205
+ @employee.save!
206
+ @employee.reload
207
+ @employee.description.should == "Second Last"
208
+ end
209
+
210
+ it "should rollback record when exception is raised in after_update callback" do
211
+ TestEmployee.after_update :raise_make_transaction_rollback
212
+
213
+ @employee = TestEmployee.create(
214
+ :first_name => "First",
215
+ :last_name => "Last",
216
+ :hire_date => @today,
217
+ :description => "description"
218
+ )
219
+ empl_id = @employee.id
220
+ @employee.reload
221
+ @employee.first_name = "Second"
222
+ lambda {
223
+ @employee.save
224
+ }.should raise_error("Make the transaction rollback")
225
+ @employee.reload
226
+ @employee.first_name.should == "First"
227
+ end
228
+
229
+ it "should not update record if nothing is changed and partial updates are enabled" do
230
+ return pending("Not in this ActiveRecord version") unless TestEmployee.respond_to?(:partial_updates=)
231
+ TestEmployee.partial_updates = true
232
+ @employee = TestEmployee.create(
233
+ :first_name => "First",
234
+ :last_name => "Last",
235
+ :hire_date => @today
236
+ )
237
+ @employee.reload
238
+ @employee.save!
239
+ @employee.reload
240
+ @employee.version.should == 1
241
+ end
242
+
243
+ it "should update record if nothing is changed and partial updates are disabled" do
244
+ return pending("Not in this ActiveRecord version") unless TestEmployee.respond_to?(:partial_updates=)
245
+ TestEmployee.partial_updates = false
246
+ @employee = TestEmployee.create(
247
+ :first_name => "First",
248
+ :last_name => "Last",
249
+ :hire_date => @today
250
+ )
251
+ @employee.reload
252
+ @employee.save!
253
+ @employee.reload
254
+ @employee.version.should == 2
255
+ end
256
+
257
+ it "should delete record" do
258
+ @employee = TestEmployee.create(
259
+ :first_name => "First",
260
+ :last_name => "Last",
261
+ :hire_date => @today
262
+ )
263
+ @employee.reload
264
+ empl_id = @employee.id
265
+ @employee.destroy
266
+ @employee.should be_frozen
267
+ TestEmployee.find_by_employee_id(empl_id).should be_nil
268
+ end
269
+
270
+ it "should delete record and set destroyed flag" do
271
+ return pending("Not in this ActiveRecord version (requires >= 2.3.5)") unless TestEmployee.method_defined?(:destroyed?)
272
+ @employee = TestEmployee.create(
273
+ :first_name => "First",
274
+ :last_name => "Last",
275
+ :hire_date => @today
276
+ )
277
+ @employee.reload
278
+ @employee.destroy
279
+ @employee.should be_destroyed
280
+ end
281
+
282
+ it "should rollback record when exception is raised in after_destroy callback" do
283
+ set_logger
284
+ TestEmployee.after_destroy :raise_make_transaction_rollback
285
+
286
+ @employee = TestEmployee.create(
287
+ :first_name => "First",
288
+ :last_name => "Last",
289
+ :hire_date => @today
290
+ )
291
+ @employee.reload
292
+ empl_id = @employee.id
293
+ lambda {
294
+ @employee.destroy
295
+ }.should raise_error("Make the transaction rollback")
296
+ @employee.id.should == empl_id
297
+ TestEmployee.find_by_employee_id(empl_id).should_not be_nil
298
+ end
299
+
300
+ it "should set timestamps when creating record" do
301
+ @employee = TestEmployee.create(
302
+ :first_name => "First",
303
+ :last_name => "Last",
304
+ :hire_date => @today
305
+ )
306
+ @employee.created_at.should_not be_nil
307
+ @employee.updated_at.should_not be_nil
308
+ end
309
+
310
+ it "should set timestamps when updating record" do
311
+ @employee = TestEmployee.create(
312
+ :first_name => "First",
313
+ :last_name => "Last",
314
+ :hire_date => @today
315
+ )
316
+ @employee.reload
317
+ @employee.created_at.should be_nil
318
+ @employee.updated_at.should be_nil
319
+ @employee.first_name = "Second"
320
+ @employee.save!
321
+ @employee.created_at.should be_nil
322
+ @employee.updated_at.should_not be_nil
323
+ end
324
+
325
+ it "should log create record" do
326
+ set_logger
327
+ @employee = TestEmployee.create(
328
+ :first_name => "First",
329
+ :last_name => "Last",
330
+ :hire_date => @today
331
+ )
332
+ @logger.logged(:debug).last.should match(/^TestEmployee Create \(\d+\.\d+(ms)?\) custom create method$/)
333
+ end
334
+
335
+ it "should log update record" do
336
+ (TestEmployee.partial_updates = false) rescue nil
337
+ @employee = TestEmployee.create(
338
+ :first_name => "First",
339
+ :last_name => "Last",
340
+ :hire_date => @today
341
+ )
342
+ set_logger
343
+ @employee.save!
344
+ @logger.logged(:debug).last.should match(/^TestEmployee Update \(\d+\.\d+(ms)?\) custom update method with employee_id=#{@employee.id}$/)
345
+ end
346
+
347
+ it "should log delete record" do
348
+ @employee = TestEmployee.create(
349
+ :first_name => "First",
350
+ :last_name => "Last",
351
+ :hire_date => @today
352
+ )
353
+ set_logger
354
+ @employee.destroy
355
+ @logger.logged(:debug).last.should match(/^TestEmployee Destroy \(\d+\.\d+(ms)?\) custom delete method with employee_id=#{@employee.id}$/)
356
+ end
357
+
358
+ it "should validate new record before creation" do
359
+ @employee = TestEmployee.new(
360
+ :last_name => "Last",
361
+ :hire_date => @today
362
+ )
363
+ @employee.save.should be_false
364
+ @employee.errors[:first_name].should_not be_blank
365
+ end
366
+
367
+ it "should validate existing record before update" do
368
+ @employee = TestEmployee.create(
369
+ :first_name => "First",
370
+ :last_name => "Last",
371
+ :hire_date => @today
372
+ )
373
+ @employee.first_name = nil
374
+ @employee.save.should be_false
375
+ @employee.errors[:first_name].should_not be_blank
376
+ end
377
+
378
+ end