ctreatma-activerecord-oracle_enhanced-adapter 1.4.1.1

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