From a83e6b1b6aa8ee67a47658ed27481e38aa2a62da Mon Sep 17 00:00:00 2001 From: Raimonds Simanovskis Date: Mon, 15 Feb 2010 00:38:29 +0200 Subject: downcase table names in aliased_table_name_for and references_eager_loaded_tables? methods (as Oracle quoted table names are in uppercase) --- activerecord/lib/active_record/relation.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 4e62187449..b6b4085ec0 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -356,13 +356,15 @@ module ActiveRecord end def references_eager_loaded_tables? - joined_tables = (tables_in_string(arel.joins(arel)) + [table.name, table.table_alias]).compact.uniq + # always convert table names to downcase as in Oracle quoted table names are in uppercase + joined_tables = (tables_in_string(arel.joins(arel)) + [table.name, table.table_alias]).compact.map(&:downcase).uniq (tables_in_string(to_sql) - joined_tables).any? end def tables_in_string(string) return [] if string.blank? - string.scan(/([a-zA-Z_][\.\w]+).?\./).flatten.uniq + # always convert table names to downcase as in Oracle quoted table names are in uppercase + string.scan(/([a-zA-Z_][\.\w]+).?\./).flatten.map(&:downcase).uniq end end -- cgit v1.2.3 From edf79a7fe7c78e291c06a6d8be3ae87dabde9afa Mon Sep 17 00:00:00 2001 From: Raimonds Simanovskis Date: Sun, 16 May 2010 20:26:40 +0300 Subject: Downcase quoted table name in regex in count_aliases_from_table_joins Oracle adapter's quote_table_name returns quoted table name in uppercase and therefore it should be downcased before scanning downcased join_sql --- activerecord/lib/active_record/associations.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 5b0ba86308..7d5fd8e96c 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1755,7 +1755,8 @@ module ActiveRecord end def count_aliases_from_table_joins(name) - quoted_name = join_base.active_record.connection.quote_table_name(name.downcase) + # quoted_name should be downcased as some database adapters (Oracle) return quoted name in uppercase + quoted_name = join_base.active_record.connection.quote_table_name(name.downcase).downcase join_sql = join_base.table_joins.to_s.downcase join_sql.blank? ? 0 : # Table names -- cgit v1.2.3 From c51fa6bdfc202f78907a7d1cb6bce7b0e2562913 Mon Sep 17 00:00:00 2001 From: Raimonds Simanovskis Date: Mon, 17 May 2010 00:19:18 +0300 Subject: ignore raw_sql_ table alias that is used by Oracle adapter --- activerecord/lib/active_record/relation.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index b6b4085ec0..99c914d7fc 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -364,7 +364,8 @@ module ActiveRecord def tables_in_string(string) return [] if string.blank? # always convert table names to downcase as in Oracle quoted table names are in uppercase - string.scan(/([a-zA-Z_][\.\w]+).?\./).flatten.map(&:downcase).uniq + # ignore raw_sql_ that is used by Oracle adapter as alias for limit/offset subqueries + string.scan(/([a-zA-Z_][\.\w]+).?\./).flatten.map(&:downcase).uniq - ['raw_sql_'] end end -- cgit v1.2.3 From a4eaa1fd39f93eff975bfd8a5cc4c7dfc3f18aa7 Mon Sep 17 00:00:00 2001 From: Ernie Miller Date: Sat, 22 May 2010 15:31:06 -0400 Subject: Fix multiple self-referencing eager loads failing to join multiple times [#4679 state:committed] Signed-off-by: Jeremy Kemper --- activerecord/lib/active_record/associations.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 95d76ae456..c1e16d08cb 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1903,7 +1903,7 @@ module ActiveRecord end def ==(other) - other.is_a?(JoinBase) && + other.class == self.class && other.active_record == active_record && other.table_joins == table_joins end @@ -1974,7 +1974,7 @@ module ActiveRecord end def ==(other) - other.is_a?(JoinAssociation) && + other.class == self.class && other.reflection == reflection && other.parent == parent end -- cgit v1.2.3 From eb69721c9bf2bd0f8957a231ecc91080b0645b84 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 8 Jun 2010 10:25:41 -0400 Subject: forcing encoding on 1.9 when dealing with "binary" columns [#4612 state:resolved] Signed-off-by: wycats --- activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb index e8a45bb3c6..deb62e3802 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb @@ -34,6 +34,10 @@ module ActiveRecord end def binary_to_string(value) + if value.respond_to?(:force_encoding) && value.encoding != Encoding::ASCII_8BIT + value = value.force_encoding(Encoding::ASCII_8BIT) + end + value.gsub(/%00|%25/n) do |b| case b when "%00" then "\0" -- cgit v1.2.3 From 32d4330b8185caa05af6ae69b0769b34b5e159eb Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Tue, 8 Jun 2010 14:46:26 -0400 Subject: Get ready for beta 4 --- activerecord/lib/active_record/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/version.rb b/activerecord/lib/active_record/version.rb index bf6b995a37..d18fed0131 100644 --- a/activerecord/lib/active_record/version.rb +++ b/activerecord/lib/active_record/version.rb @@ -3,7 +3,7 @@ module ActiveRecord MAJOR = 3 MINOR = 0 TINY = 0 - BUILD = "beta3" + BUILD = "beta4" STRING = [MAJOR, MINOR, TINY, BUILD].join('.') end -- cgit v1.2.3 From 1b2941cba1165b0721f57524645fe378bee2a950 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Tue, 8 Jun 2010 14:40:20 -0400 Subject: Temporarily revert "Update after_commit and after_rollback docs and tests to use new style API with an :on options instead of on_* suffix." and "Add after_commit and after_rollback callbacks to ActiveRecord that are called after transactions either commit or rollback on all records saved or destroyed in the transaction." This reverts commits d2a49e4b1f30c5997e169110eed94a55aee53f56 and da840d13da865331297d5287391231b1ed39721b. [#2991] Conflicts: activerecord/CHANGELOG activerecord/lib/active_record/transactions.rb activerecord/test/cases/transaction_callbacks_test.rb --- .../abstract/database_statements.rb | 56 ---------- activerecord/lib/active_record/transactions.rb | 118 ++------------------- 2 files changed, 9 insertions(+), 165 deletions(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb index b9fb452eee..0c87e052c4 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb @@ -122,8 +122,6 @@ module ActiveRecord requires_new = options[:requires_new] || !last_transaction_joinable transaction_open = false - @_current_transaction_records ||= [] - begin if block_given? if requires_new || open_transactions == 0 @@ -134,7 +132,6 @@ module ActiveRecord end increment_open_transactions transaction_open = true - @_current_transaction_records.push([]) end yield end @@ -144,10 +141,8 @@ module ActiveRecord decrement_open_transactions if open_transactions == 0 rollback_db_transaction - rollback_transaction_records(true) else rollback_to_savepoint - rollback_transaction_records(false) end end raise unless database_transaction_rollback.is_a?(ActiveRecord::Rollback) @@ -162,35 +157,20 @@ module ActiveRecord begin if open_transactions == 0 commit_db_transaction - commit_transaction_records else release_savepoint - save_point_records = @_current_transaction_records.pop - unless save_point_records.blank? - @_current_transaction_records.push([]) if @_current_transaction_records.empty? - @_current_transaction_records.last.concat(save_point_records) - end end rescue Exception => database_transaction_rollback if open_transactions == 0 rollback_db_transaction - rollback_transaction_records(true) else rollback_to_savepoint - rollback_transaction_records(false) end raise end end end - # Register a record with the current transaction so that its after_commit and after_rollback callbacks - # can be called. - def add_transaction_record(record) - last_batch = @_current_transaction_records.last - last_batch << record if last_batch - end - # Begins the transaction (and turns off auto-committing). def begin_db_transaction() end @@ -288,42 +268,6 @@ module ActiveRecord limit.to_i end end - - # Send a rollback message to all records after they have been rolled back. If rollback - # is false, only rollback records since the last save point. - def rollback_transaction_records(rollback) #:nodoc - if rollback - records = @_current_transaction_records.flatten - @_current_transaction_records.clear - else - records = @_current_transaction_records.pop - end - - unless records.blank? - records.uniq.each do |record| - begin - record.rolledback!(rollback) - rescue Exception => e - record.logger.error(e) if record.respond_to?(:logger) - end - end - end - end - - # Send a commit message to all records after they have been committed. - def commit_transaction_records #:nodoc - records = @_current_transaction_records.flatten - @_current_transaction_records.clear - unless records.blank? - records.uniq.each do |record| - begin - record.committed! - rescue Exception => e - record.logger.error(e) if record.respond_to?(:logger) - end - end - end - end end end end diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb index 5a8e2ce880..3f2c1911e7 100644 --- a/activerecord/lib/active_record/transactions.rb +++ b/activerecord/lib/active_record/transactions.rb @@ -8,11 +8,6 @@ module ActiveRecord class TransactionError < ActiveRecordError # :nodoc: end - included do - define_model_callbacks :commit, :commit_on_update, :commit_on_create, :commit_on_destroy, :only => :after - define_model_callbacks :rollback, :rollback_on_update, :rollback_on_create, :rollback_on_destroy - end - # Transactions are protective blocks where SQL statements are only permanent # if they can all succeed as one atomic action. The classic example is a # transfer between two accounts where you can only have a deposit if the @@ -163,21 +158,6 @@ module ActiveRecord # http://dev.mysql.com/doc/refman/5.0/en/savepoints.html # for more information about savepoints. # - # === Callbacks - # - # There are two types of callbacks associated with committing and rolling back transactions: - # +after_commit+ and +after_rollback+. - # - # +after_commit+ callbacks are called on every record saved or destroyed within a - # transaction immediately after the transaction is committed. +after_rollback+ callbacks - # are called on every record saved or destroyed within a transaction immediately after the - # transaction or savepoint is rolled back. - # - # These callbacks are useful for interacting with other systems since you will be guaranteed - # that the callback is only executed when the database is in a permanent state. For example, - # +after_commit+ is a good spot to put in a hook to clearing a cache since clearing it from - # within a transaction could trigger the cache to be regenerated before the database is updated. - # # === Caveats # # If you're on MySQL, then do not use DDL operations in nested transactions @@ -225,50 +205,19 @@ module ActiveRecord # Reset id and @new_record if the transaction rolls back. def rollback_active_record_state! - remember_transaction_record_state + id_present = has_attribute?(self.class.primary_key) + previous_id = id + previous_new_record = new_record? yield rescue Exception - restore_transaction_record_state - raise - ensure - clear_transaction_record_state - end - - # Call the after_commit callbacks - def committed! #:nodoc: - if transaction_record_state(:new_record) - _run_commit_on_create_callbacks - elsif transaction_record_state(:destroyed) - _run_commit_on_destroy_callbacks + @new_record = previous_new_record + if id_present + self.id = previous_id else - _run_commit_on_update_callbacks - end - _run_commit_callbacks - ensure - clear_transaction_record_state - end - - # Call the after rollback callbacks. The restore_state argument indicates if the record - # state should be rolled back to the beginning or just to the last savepoint. - def rolledback!(force_restore_state = false) #:nodoc: - if transaction_record_state(:new_record) - _run_rollback_on_create_callbacks - elsif transaction_record_state(:destroyed) - _run_rollback_on_destroy_callbacks - else - _run_rollback_on_update_callbacks - end - _run_rollback_callbacks - ensure - restore_transaction_record_state(force_restore_state) - end - - # Add the record to the current transaction so that the :after_rollback and :after_commit callbacks - # can be called. - def add_to_transaction - if self.class.connection.add_transaction_record(self) - remember_transaction_record_state + @attributes.delete(self.class.primary_key) + @attributes_cache.delete(self.class.primary_key) end + raise end # Executes +method+ within a transaction and captures its return value as a @@ -280,59 +229,10 @@ module ActiveRecord def with_transaction_returning_status status = nil self.class.transaction do - add_to_transaction status = yield raise ActiveRecord::Rollback unless status end status end - - protected - - # Save the new record state and id of a record so it can be restored later if a transaction fails. - def remember_transaction_record_state #:nodoc - @_start_transaction_state ||= {} - unless @_start_transaction_state.include?(:new_record) - @_start_transaction_state[:id] = id if has_attribute?(self.class.primary_key) - @_start_transaction_state[:new_record] = @new_record - end - unless @_start_transaction_state.include?(:destroyed) - @_start_transaction_state[:destroyed] = @new_record - end - @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) + 1 - end - - # Clear the new record state and id of a record. - def clear_transaction_record_state #:nodoc - if defined?(@_start_transaction_state) - @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1 - remove_instance_variable(:@_start_transaction_state) if @_start_transaction_state[:level] < 1 - end - end - - # Restore the new record state and id of a record that was previously saved by a call to save_record_state. - def restore_transaction_record_state(force = false) #:nodoc - if defined?(@_start_transaction_state) - @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1 - if @_start_transaction_state[:level] < 1 - restore_state = remove_instance_variable(:@_start_transaction_state) - if restore_state - @new_record = restore_state[:new_record] - @destroyed = restore_state[:destroyed] - if restore_state[:id] - self.id = restore_state[:id] - else - @attributes.delete(self.class.primary_key) - @attributes_cache.delete(self.class.primary_key) - end - end - end - end - end - - # Determine if a record was created or destroyed in a transaction. State should be one of :new_record or :destroyed. - def transaction_record_state(state) #:nodoc - @_start_transaction_state[state] if defined?(@_start_transaction_state) - end end end -- cgit v1.2.3