activerecord-oracle_enhanced-adapter-with-schema 0.0.1

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 (46) hide show
  1. data/.rspec +2 -0
  2. data/Gemfile +52 -0
  3. data/History.md +301 -0
  4. data/License.txt +20 -0
  5. data/README.md +123 -0
  6. data/RUNNING_TESTS.md +45 -0
  7. data/Rakefile +59 -0
  8. data/VERSION +1 -0
  9. data/activerecord-oracle_enhanced-adapter-with-schema.gemspec +130 -0
  10. data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +5 -0
  11. data/lib/active_record/connection_adapters/oracle_enhanced.rake +105 -0
  12. data/lib/active_record/connection_adapters/oracle_enhanced_activerecord_patches.rb +41 -0
  13. data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +1399 -0
  14. data/lib/active_record/connection_adapters/oracle_enhanced_base_ext.rb +121 -0
  15. data/lib/active_record/connection_adapters/oracle_enhanced_column.rb +146 -0
  16. data/lib/active_record/connection_adapters/oracle_enhanced_connection.rb +119 -0
  17. data/lib/active_record/connection_adapters/oracle_enhanced_context_index.rb +359 -0
  18. data/lib/active_record/connection_adapters/oracle_enhanced_core_ext.rb +25 -0
  19. data/lib/active_record/connection_adapters/oracle_enhanced_cpk.rb +21 -0
  20. data/lib/active_record/connection_adapters/oracle_enhanced_dirty.rb +46 -0
  21. data/lib/active_record/connection_adapters/oracle_enhanced_jdbc_connection.rb +565 -0
  22. data/lib/active_record/connection_adapters/oracle_enhanced_oci_connection.rb +494 -0
  23. data/lib/active_record/connection_adapters/oracle_enhanced_procedures.rb +260 -0
  24. data/lib/active_record/connection_adapters/oracle_enhanced_schema_definitions.rb +227 -0
  25. data/lib/active_record/connection_adapters/oracle_enhanced_schema_dumper.rb +260 -0
  26. data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb +428 -0
  27. data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements_ext.rb +258 -0
  28. data/lib/active_record/connection_adapters/oracle_enhanced_structure_dump.rb +294 -0
  29. data/lib/active_record/connection_adapters/oracle_enhanced_tasks.rb +17 -0
  30. data/lib/active_record/connection_adapters/oracle_enhanced_version.rb +1 -0
  31. data/lib/activerecord-oracle_enhanced-adapter-with-schema.rb +25 -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 +1388 -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 +440 -0
  43. data/spec/active_record/connection_adapters/oracle_enhanced_schema_statements_spec.rb +1385 -0
  44. data/spec/active_record/connection_adapters/oracle_enhanced_structure_dump_spec.rb +339 -0
  45. data/spec/spec_helper.rb +189 -0
  46. metadata +260 -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