activerecord 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- data/CHANGELOG +65 -0
- data/install.rb +2 -2
- data/lib/active_record.rb +1 -1
- data/lib/active_record/acts/list.rb +13 -13
- data/lib/active_record/associations.rb +38 -0
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +1 -1
- data/lib/active_record/associations/has_many_association.rb +2 -1
- data/lib/active_record/base.rb +44 -20
- data/lib/active_record/connection_adapters/abstract_adapter.rb +10 -11
- data/lib/active_record/connection_adapters/mysql_adapter.rb +6 -2
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +7 -2
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +10 -2
- data/lib/active_record/fixtures.rb +18 -0
- data/lib/active_record/support/binding_of_caller.rb +81 -0
- data/lib/active_record/support/breakpoint.rb +525 -0
- data/lib/active_record/timestamp.rb +17 -5
- data/lib/active_record/transactions.rb +11 -13
- data/lib/active_record/validations.rb +31 -13
- data/rakefile +1 -1
- data/test/abstract_unit.rb +2 -0
- data/test/base_test.rb +29 -9
- data/test/fixtures/db_definitions/mysql.sql +5 -3
- data/test/fixtures/db_definitions/postgresql.sql +2 -0
- data/test/fixtures/db_definitions/sqlite.sql +3 -1
- data/test/fixtures/db_definitions/sqlserver.sql +2 -0
- data/test/fixtures/developer.rb +2 -4
- data/test/fixtures/developers.yml +3 -0
- data/test/fixtures/fixture_database.sqlite +0 -0
- data/test/fixtures/fixture_database_2.sqlite +0 -0
- data/test/fixtures/mixin.rb +5 -2
- data/test/fixtures/mixins.yml +27 -11
- data/test/mixin_test.rb +154 -56
- data/test/transactions_test.rb +1 -1
- data/test/validations_test.rb +50 -3
- metadata +4 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,68 @@
|
|
1
|
+
*1.3.0*
|
2
|
+
|
3
|
+
* Added a require_association hook on const_missing that makes it possible to use any model class without requiring it first. This makes STI look like:
|
4
|
+
|
5
|
+
before:
|
6
|
+
require_association 'person'
|
7
|
+
class Employee < Person
|
8
|
+
end
|
9
|
+
|
10
|
+
after:
|
11
|
+
class Employee < Person
|
12
|
+
end
|
13
|
+
|
14
|
+
This also reduces the usefulness of Controller.model in Action Pack to currently only being for documentation purposes.
|
15
|
+
|
16
|
+
* Added that Base.update_all and Base.delete_all return an integer of the number of affected rows #341
|
17
|
+
|
18
|
+
* Added scope option to validation_uniqueness #349 [Kent Sibilev]
|
19
|
+
|
20
|
+
* Added respondence to *_before_type_cast for all attributes to return their string-state before they were type casted by the column type.
|
21
|
+
This is helpful for getting "100,000" back on a integer-based validation where the value would normally be "100".
|
22
|
+
|
23
|
+
* Added allow_nil options to validates_inclusion_of so that validation is only triggered if the attribute is not nil [what-a-day]
|
24
|
+
|
25
|
+
* Added work-around for PostgreSQL and the problem of getting fixtures to be created from id 1 on each test case.
|
26
|
+
This only works for auto-incrementing primary keys called "id" for now #359 [Scott Baron]
|
27
|
+
|
28
|
+
* Added Base#clear_association_cache to empty all the cached associations #347 [Tobias Luetke]
|
29
|
+
|
30
|
+
* Added more informative exceptions in establish_connection #356 [bitsweat]
|
31
|
+
|
32
|
+
* Added Base#update_attributes that'll accept a hash of attributes and save the record (returning true if it passed validation, false otherwise).
|
33
|
+
|
34
|
+
Before:
|
35
|
+
person.attributes = @params["person"]
|
36
|
+
person.save
|
37
|
+
|
38
|
+
Now:
|
39
|
+
person.update_attributes(@params["person"])
|
40
|
+
|
41
|
+
* Added Base.destroy and Base.delete to remove records without holding a reference to them first.
|
42
|
+
|
43
|
+
* Added that query benchmarking will only happen if its going to be logged anyway #344
|
44
|
+
|
45
|
+
* Added higher_item and lower_item as public methods for acts_as_list #342 [Tobias Luetke]
|
46
|
+
|
47
|
+
* Fixed that options[:counter_sql] was overwritten with interpolated sql rather than original sql #355 [bitsweat]
|
48
|
+
|
49
|
+
* Fixed that overriding an attribute's accessor would be disregarded by add_on_empty and add_on_boundary_breaking because they simply used
|
50
|
+
the attributes[] hash instead of checking for @base.respond_to?(attr.to_s). [Marten]
|
51
|
+
|
52
|
+
* Fixed that Base.table_name would expect a parameter when used in has_and_belongs_to_many joins [Anna Lissa Cruz]
|
53
|
+
|
54
|
+
* Fixed that nested transactions now work by letting the outer most transaction have the responsibilty of starting and rolling back the transaction.
|
55
|
+
If any of the inner transactions swallow the exception raised, though, the transaction will not be rolled back. So always let the transaction
|
56
|
+
bubble up even when you've dealt with local issues. Closes #231 and #340.
|
57
|
+
|
58
|
+
* Fixed validates_{confirmation,acceptance}_of to only happen when the virtual attributes are not nil #348 [dpiddy@gmail.com]
|
59
|
+
|
60
|
+
* Changed the interface on AbstractAdapter to require that adapters return the number of affected rows on delete and update operations.
|
61
|
+
|
62
|
+
* Fixed the automated timestamping feature when running under Rails' development environment that resets the inheritable attributes on each request.
|
63
|
+
|
64
|
+
|
65
|
+
|
1
66
|
*1.2.0*
|
2
67
|
|
3
68
|
* Added Base.validates_inclusion_of that validates whether the value of the specified attribute is available in a particular enumerable
|
data/install.rb
CHANGED
@@ -42,8 +42,8 @@ files = %w-
|
|
42
42
|
active_record/fixtures.rb
|
43
43
|
active_record/observer.rb
|
44
44
|
active_record/reflection.rb
|
45
|
-
active_record/
|
46
|
-
active_record/
|
45
|
+
active_record/acts/list.rb
|
46
|
+
active_record/acts/tree.rb
|
47
47
|
active_record/support/class_attribute_accessors.rb
|
48
48
|
active_record/support/class_inheritable_attributes.rb
|
49
49
|
active_record/support/clean_logger.rb
|
data/lib/active_record.rb
CHANGED
@@ -41,12 +41,12 @@ require 'active_record/acts/tree'
|
|
41
41
|
|
42
42
|
ActiveRecord::Base.class_eval do
|
43
43
|
include ActiveRecord::Validations
|
44
|
+
include ActiveRecord::Timestamp
|
44
45
|
include ActiveRecord::Callbacks
|
45
46
|
include ActiveRecord::Associations
|
46
47
|
include ActiveRecord::Aggregations
|
47
48
|
include ActiveRecord::Transactions
|
48
49
|
include ActiveRecord::Reflection
|
49
|
-
include ActiveRecord::Timestamp
|
50
50
|
include ActiveRecord::Acts::Tree
|
51
51
|
include ActiveRecord::Acts::List
|
52
52
|
end
|
@@ -109,6 +109,18 @@ module ActiveRecord
|
|
109
109
|
def last?
|
110
110
|
self.send(position_column) == bottom_position_in_list
|
111
111
|
end
|
112
|
+
|
113
|
+
def higher_item
|
114
|
+
self.class.find_first(
|
115
|
+
"#{scope_condition} AND #{position_column} = #{(send(position_column).to_i - 1).to_s}"
|
116
|
+
)
|
117
|
+
end
|
118
|
+
|
119
|
+
def lower_item
|
120
|
+
self.class.find_first(
|
121
|
+
"#{scope_condition} AND #{position_column} = #{(send(position_column).to_i + 1).to_s}"
|
122
|
+
)
|
123
|
+
end
|
112
124
|
|
113
125
|
private
|
114
126
|
|
@@ -123,18 +135,6 @@ module ActiveRecord
|
|
123
135
|
# Overwrite this method to define the scope of the list changes
|
124
136
|
def scope_condition() "1" end
|
125
137
|
|
126
|
-
def higher_item
|
127
|
-
self.class.find_first(
|
128
|
-
"#{scope_condition} AND #{position_column} = #{(send(position_column).to_i - 1).to_s}"
|
129
|
-
)
|
130
|
-
end
|
131
|
-
|
132
|
-
def lower_item
|
133
|
-
self.class.find_first(
|
134
|
-
"#{scope_condition} AND #{position_column} = #{(send(position_column).to_i + 1).to_s}"
|
135
|
-
)
|
136
|
-
end
|
137
|
-
|
138
138
|
def bottom_position_in_list
|
139
139
|
item = bottom_item
|
140
140
|
item ? item.send(position_column) : 0
|
@@ -163,7 +163,7 @@ module ActiveRecord
|
|
163
163
|
|
164
164
|
def increment_positions_on_higher_items
|
165
165
|
self.class.update_all(
|
166
|
-
"#{position_column} = (#{position_column} + 1)", "#{scope_condition} AND #{position_column} < #{send(position_column)}"
|
166
|
+
"#{position_column} = (#{position_column} + 1)", "#{scope_condition} AND #{position_column} < #{send(position_column).to_i}"
|
167
167
|
)
|
168
168
|
end
|
169
169
|
|
@@ -3,10 +3,30 @@ require 'active_record/associations/has_many_association'
|
|
3
3
|
require 'active_record/associations/has_and_belongs_to_many_association'
|
4
4
|
require 'active_record/deprecated_associations'
|
5
5
|
|
6
|
+
|
6
7
|
unless Object.respond_to?(:require_association)
|
7
8
|
Object.send(:define_method, :require_association) { |file_name| ActiveRecord::Base.require_association(file_name) }
|
8
9
|
end
|
9
10
|
|
11
|
+
class Object
|
12
|
+
class << self
|
13
|
+
# Use const_missing to autoload associations so we don't have to
|
14
|
+
# require_association when using single-table inheritance.
|
15
|
+
unless respond_to?(:pre_association_const_missing)
|
16
|
+
alias_method :pre_association_const_missing, :const_missing
|
17
|
+
|
18
|
+
def const_missing(class_id)
|
19
|
+
begin
|
20
|
+
require_association(Inflector.underscore(Inflector.demodulize(class_id.to_s)))
|
21
|
+
return Object.const_get(class_id) if Object.const_get(class_id).ancestors.include?(ActiveRecord::Base)
|
22
|
+
rescue LoadError
|
23
|
+
pre_association_const_missing(class_id)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
10
30
|
module ActiveRecord
|
11
31
|
module Associations # :nodoc:
|
12
32
|
def self.append_features(base)
|
@@ -14,6 +34,13 @@ module ActiveRecord
|
|
14
34
|
base.extend(ClassMethods)
|
15
35
|
end
|
16
36
|
|
37
|
+
# Clears out the association cache
|
38
|
+
def clear_association_cache #:nodoc:
|
39
|
+
self.class.reflect_on_all_associations.to_a.each do |assoc|
|
40
|
+
instance_variable_set "@#{assoc.name}", nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
17
44
|
# Associations are a set of macro-like class methods for tying objects together through foreign keys. They express relationships like
|
18
45
|
# "Project has one Project Manager" or "Project belongs to a Portfolio". Each macro adds a number of methods to the class which are
|
19
46
|
# specialized according to the collection or association symbol and the options hash. It works much the same was as Ruby's own attr*
|
@@ -464,6 +491,17 @@ module ActiveRecord
|
|
464
491
|
def reset_associations_loaded
|
465
492
|
self.associations_loaded = []
|
466
493
|
end
|
494
|
+
|
495
|
+
# Reload all the associations that have already been loaded once.
|
496
|
+
def reload_associations_loaded
|
497
|
+
associations_loaded.each do |file_name|
|
498
|
+
begin
|
499
|
+
silence_warnings { load("#{file_name}.rb") }
|
500
|
+
rescue LoadError
|
501
|
+
# The association didn't reside in its own file, so we assume it was required by other means
|
502
|
+
end
|
503
|
+
end
|
504
|
+
end
|
467
505
|
|
468
506
|
private
|
469
507
|
# Raises an exception if an invalid option has been specified to prevent misspellings from slipping through
|
@@ -5,7 +5,7 @@ module ActiveRecord
|
|
5
5
|
super(owner, association_name, association_class_name, association_class_primary_key_name, options)
|
6
6
|
|
7
7
|
@association_foreign_key = options[:association_foreign_key] || Inflector.underscore(Inflector.demodulize(association_class_name)) + "_id"
|
8
|
-
association_table_name = options[:table_name] || @association_class.table_name
|
8
|
+
association_table_name = options[:table_name] || @association_class.table_name
|
9
9
|
@join_table = join_table
|
10
10
|
@order = options[:order] || "t.#{@association_class.primary_key}"
|
11
11
|
|
@@ -14,7 +14,8 @@ module ActiveRecord
|
|
14
14
|
if options[:counter_sql]
|
15
15
|
@counter_sql = interpolate_sql(options[:counter_sql])
|
16
16
|
elsif options[:finder_sql]
|
17
|
-
|
17
|
+
options[:counter_sql] = options[:finder_sql].gsub(/SELECT (.*) FROM/i, "SELECT COUNT(*) FROM")
|
18
|
+
@counter_sql = interpolate_sql(options[:counter_sql])
|
18
19
|
else
|
19
20
|
@counter_sql = "#{@association_class_primary_key_name} = #{@owner.quoted_id}#{@conditions ? " AND " + interpolate_sql(@conditions) : ""}"
|
20
21
|
end
|
data/lib/active_record/base.rb
CHANGED
@@ -333,13 +333,23 @@ module ActiveRecord #:nodoc:
|
|
333
333
|
object
|
334
334
|
end
|
335
335
|
|
336
|
-
#
|
337
|
-
|
336
|
+
# Deletes the record with the given +id+ without instantiating an object first.
|
337
|
+
def delete(id)
|
338
|
+
delete_all([ "#{primary_key} = ?", id ])
|
339
|
+
end
|
340
|
+
|
341
|
+
# Destroys the record with the given +id+ by instantiating the object and calling #destroy (all the callbacks are the triggered).
|
342
|
+
def destroy(id)
|
343
|
+
find(id).destroy
|
344
|
+
end
|
345
|
+
|
346
|
+
# Updates all records with the SET-part of an SQL update statement in +updates+ and returns an integer with the number of rows updates.
|
347
|
+
# A subset of the records can be selected by specifying +conditions+. Example:
|
338
348
|
# Billing.update_all "category = 'authorized', approved = 1", "author = 'David'"
|
339
349
|
def update_all(updates, conditions = nil)
|
340
350
|
sql = "UPDATE #{table_name} SET #{updates} "
|
341
351
|
add_conditions!(sql, conditions)
|
342
|
-
connection.update(sql, "#{name} Update")
|
352
|
+
return connection.update(sql, "#{name} Update")
|
343
353
|
end
|
344
354
|
|
345
355
|
# Destroys the objects for all the records that matches the +condition+ by instantiating each object and calling
|
@@ -463,13 +473,8 @@ module ActiveRecord #:nodoc:
|
|
463
473
|
# class Mouse < ActiveRecord::Base
|
464
474
|
# def self.table_name() "mice" end
|
465
475
|
# end
|
466
|
-
def table_name
|
467
|
-
|
468
|
-
class_name = class_name_of_active_record_descendant(self)
|
469
|
-
table_name_prefix + undecorated_table_name(class_name) + table_name_suffix
|
470
|
-
else
|
471
|
-
table_name_prefix + undecorated_table_name(class_name) + table_name_suffix
|
472
|
-
end
|
476
|
+
def table_name
|
477
|
+
table_name_prefix + undecorated_table_name(class_name_of_active_record_descendant(self)) + table_name_suffix
|
473
478
|
end
|
474
479
|
|
475
480
|
# Defines the primary key field -- can be overridden in subclasses. Overwritting will negate any effect of the
|
@@ -522,6 +527,7 @@ module ActiveRecord #:nodoc:
|
|
522
527
|
methods[attr.to_sym] = true
|
523
528
|
methods["#{attr}=".to_sym] = true
|
524
529
|
methods["#{attr}?".to_sym] = true
|
530
|
+
methods["#{attr}_before_type_cast".to_sym] = true
|
525
531
|
methods
|
526
532
|
end
|
527
533
|
end
|
@@ -723,6 +729,10 @@ module ActiveRecord #:nodoc:
|
|
723
729
|
read_attribute(self.class.primary_key)
|
724
730
|
end
|
725
731
|
|
732
|
+
def id_before_type_cast
|
733
|
+
read_attribute_before_type_cast(self.class.primary_key)
|
734
|
+
end
|
735
|
+
|
726
736
|
def quoted_id
|
727
737
|
quote(id, self.class.columns_hash[self.class.primary_key])
|
728
738
|
end
|
@@ -777,9 +787,18 @@ module ActiveRecord #:nodoc:
|
|
777
787
|
end
|
778
788
|
|
779
789
|
# Updates a single attribute and saves the record. This is especially useful for boolean flags on existing records.
|
790
|
+
# Note: This method is overwritten by the Validation module that'll make sure that updates made with this method
|
791
|
+
# doesn't get subjected to validation checks. Hence, attributes can be updated even if the full object isn't valid.
|
780
792
|
def update_attribute(name, value)
|
781
793
|
self[name] = value
|
782
|
-
|
794
|
+
return true
|
795
|
+
end
|
796
|
+
|
797
|
+
# Updates all the attributes in from the passed hash and saves the record. If the object is invalid, the saving will
|
798
|
+
# fail and false will be returned.
|
799
|
+
def update_attributes(attributes)
|
800
|
+
self.attributes = attributes
|
801
|
+
return save
|
783
802
|
end
|
784
803
|
|
785
804
|
# Returns the value of attribute identified by <tt>attr_name</tt> after it has been type cast (for example,
|
@@ -901,10 +920,10 @@ module ActiveRecord #:nodoc:
|
|
901
920
|
def method_missing(method_id, *arguments)
|
902
921
|
method_name = method_id.id2name
|
903
922
|
|
904
|
-
|
905
|
-
|
906
923
|
if method_name =~ read_method? && @attributes.include?($1)
|
907
924
|
return read_attribute($1)
|
925
|
+
elsif method_name =~ read_untyped_method? && @attributes.include?($1)
|
926
|
+
return read_attribute_before_type_cast($1)
|
908
927
|
elsif method_name =~ write_method? && @attributes.include?($1)
|
909
928
|
write_attribute($1, arguments[0])
|
910
929
|
elsif method_name =~ query_method? && @attributes.include?($1)
|
@@ -914,25 +933,30 @@ module ActiveRecord #:nodoc:
|
|
914
933
|
end
|
915
934
|
end
|
916
935
|
|
917
|
-
def read_method?()
|
918
|
-
def
|
919
|
-
def
|
936
|
+
def read_method?() /^([a-zA-Z][-_\w]*)[^=?]*$/ end
|
937
|
+
def read_untyped_method?() /^([a-zA-Z][-_\w]*)_before_type_cast$/ end
|
938
|
+
def write_method?() /^([a-zA-Z][-_\w]*)=.*$/ end
|
939
|
+
def query_method?() /^([a-zA-Z][-_\w]*)\?$/ end
|
920
940
|
|
921
|
-
# Returns the value of attribute identified by <tt>attr_name</tt> after it has been type cast (for example,
|
941
|
+
# Returns the value of attribute identified by <tt>attr_name</tt> after it has been type cast (for example,
|
922
942
|
# "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)).
|
923
943
|
def read_attribute(attr_name) #:doc:
|
924
944
|
if @attributes.keys.include? attr_name
|
925
945
|
if column = column_for_attribute(attr_name)
|
926
|
-
|
946
|
+
unserializable_attribute?(attr_name, column) ?
|
927
947
|
unserialize_attribute(attr_name) : column.type_cast(@attributes[attr_name])
|
948
|
+
else
|
949
|
+
@attributes[attr_name]
|
928
950
|
end
|
929
|
-
|
930
|
-
@attributes[attr_name]
|
931
951
|
else
|
932
952
|
nil
|
933
953
|
end
|
934
954
|
end
|
935
955
|
|
956
|
+
def read_attribute_before_type_cast(attr_name)
|
957
|
+
@attributes[attr_name]
|
958
|
+
end
|
959
|
+
|
936
960
|
# Returns true if the attribute is of a text column and marked for serialization.
|
937
961
|
def unserializable_attribute?(attr_name, column)
|
938
962
|
@attributes[attr_name] && column.send(:type) == :text && @attributes[attr_name].is_a?(String) && self.class.serialized_attributes[attr_name]
|
@@ -86,14 +86,13 @@ module ActiveRecord
|
|
86
86
|
if configuration = configurations[spec.to_s]
|
87
87
|
establish_connection(configuration)
|
88
88
|
else
|
89
|
-
raise AdapterNotSpecified
|
89
|
+
raise AdapterNotSpecified, "#{spec} database is not configured"
|
90
90
|
end
|
91
91
|
else
|
92
92
|
spec = symbolize_strings_in_hash(spec)
|
93
|
-
unless spec.key?(:adapter) then raise AdapterNotSpecified end
|
94
|
-
|
93
|
+
unless spec.key?(:adapter) then raise AdapterNotSpecified, "database configuration does not specify adapter" end
|
95
94
|
adapter_method = "#{spec[:adapter]}_connection"
|
96
|
-
unless respond_to?(adapter_method) then raise AdapterNotFound end
|
95
|
+
unless respond_to?(adapter_method) then raise AdapterNotFound, "database configuration specifies nonexistent #{spec[:adapter]} adapter" end
|
97
96
|
remove_connection
|
98
97
|
establish_connection(ConnectionSpecification.new(spec, adapter_method))
|
99
98
|
end
|
@@ -285,10 +284,10 @@ module ActiveRecord
|
|
285
284
|
# Returns the last auto-generated ID from the affected table.
|
286
285
|
def insert(sql, name = nil, pk = nil, id_value = nil) end
|
287
286
|
|
288
|
-
# Executes the update statement.
|
287
|
+
# Executes the update statement and returns the number of rows affected.
|
289
288
|
def update(sql, name = nil) end
|
290
289
|
|
291
|
-
# Executes the delete statement.
|
290
|
+
# Executes the delete statement and returns the number of rows affected.
|
292
291
|
def delete(sql, name = nil) end
|
293
292
|
|
294
293
|
def reset_runtime # :nodoc:
|
@@ -298,16 +297,16 @@ module ActiveRecord
|
|
298
297
|
end
|
299
298
|
|
300
299
|
# Wrap a block in a transaction. Returns result of block.
|
301
|
-
def transaction
|
300
|
+
def transaction(start_db_transaction = true)
|
302
301
|
begin
|
303
302
|
if block_given?
|
304
|
-
begin_db_transaction
|
303
|
+
begin_db_transaction if start_db_transaction
|
305
304
|
result = yield
|
306
|
-
commit_db_transaction
|
305
|
+
commit_db_transaction if start_db_transaction
|
307
306
|
result
|
308
307
|
end
|
309
308
|
rescue Exception => database_transaction_rollback
|
310
|
-
rollback_db_transaction
|
309
|
+
rollback_db_transaction if start_db_transaction
|
311
310
|
raise
|
312
311
|
end
|
313
312
|
end
|
@@ -349,7 +348,7 @@ module ActiveRecord
|
|
349
348
|
protected
|
350
349
|
def log(sql, name, connection, &action)
|
351
350
|
begin
|
352
|
-
if @logger.nil?
|
351
|
+
if @logger.nil? || @logger.level > Logger::INFO
|
353
352
|
action.call(connection)
|
354
353
|
else
|
355
354
|
result = nil
|
@@ -67,8 +67,12 @@ module ActiveRecord
|
|
67
67
|
log(sql, name, @connection) { |connection| connection.query(sql) }
|
68
68
|
end
|
69
69
|
|
70
|
-
|
71
|
-
|
70
|
+
def update(sql, name = nil)
|
71
|
+
execute(sql, name)
|
72
|
+
@connection.affected_rows
|
73
|
+
end
|
74
|
+
|
75
|
+
alias_method :delete, :update
|
72
76
|
|
73
77
|
def begin_db_transaction
|
74
78
|
begin
|
@@ -64,8 +64,13 @@ module ActiveRecord
|
|
64
64
|
log(sql, name, @connection) { |connection| connection.query(sql) }
|
65
65
|
end
|
66
66
|
|
67
|
-
|
68
|
-
|
67
|
+
def update(sql, name = nil)
|
68
|
+
result = nil
|
69
|
+
log(sql, name, @connection) { |connection| result = connection.exec(sql) }
|
70
|
+
result.cmdtuples
|
71
|
+
end
|
72
|
+
|
73
|
+
alias_method :delete, :update
|
69
74
|
|
70
75
|
def begin_db_transaction() execute "BEGIN" end
|
71
76
|
def commit_db_transaction() execute "COMMIT" end
|
@@ -62,8 +62,16 @@ module ActiveRecord
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
|
66
|
-
|
65
|
+
def update(sql, name = nil)
|
66
|
+
execute(sql, name)
|
67
|
+
@connection.changes
|
68
|
+
end
|
69
|
+
|
70
|
+
def delete(sql, name = nil)
|
71
|
+
sql += " WHERE 1=1" unless sql =~ /WHERE/i
|
72
|
+
execute(sql, name)
|
73
|
+
@connection.changes
|
74
|
+
end
|
67
75
|
|
68
76
|
def begin_db_transaction() execute "BEGIN" end
|
69
77
|
def commit_db_transaction() execute "COMMIT" end
|