diff options
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r-- | activerecord/lib/active_record/locking/optimistic.rb | 33 | ||||
-rw-r--r-- | activerecord/lib/active_record/migration.rb | 59 |
2 files changed, 47 insertions, 45 deletions
diff --git a/activerecord/lib/active_record/locking/optimistic.rb b/activerecord/lib/active_record/locking/optimistic.rb index 7fa7e267d8..ab0f5fc58d 100644 --- a/activerecord/lib/active_record/locking/optimistic.rb +++ b/activerecord/lib/active_record/locking/optimistic.rb @@ -89,14 +89,19 @@ module ActiveRecord attribute_names.uniq! begin - affected_rows = connection.update(<<-end_sql, "#{self.class.name} Update with optimistic locking") - UPDATE #{self.class.quoted_table_name} - SET #{quoted_comma_pair_list(connection, attributes_with_quotes(false, false, attribute_names))} - WHERE #{self.class.primary_key} = #{quote_value(id)} - AND #{self.class.quoted_locking_column} = #{quote_value(previous_value)} - end_sql - - unless affected_rows == 1 + table = Arel(self.class.table_name) + affected_rows = table.where( + table[self.class.primary_key].eq(quoted_id).and( + table[self.class.locking_column].eq(quote_value(previous_value)) + ) + ) + + attributes = {} + attributes_with_quotes(false, false, attribute_names).map { |k,v| + attributes.merge!(table[k] => v) + } + + unless affected_rows.update(attributes) == 1 raise ActiveRecord::StaleObjectError, "Attempted to update a stale object" end @@ -116,12 +121,12 @@ module ActiveRecord lock_col = self.class.locking_column previous_value = send(lock_col).to_i - affected_rows = connection.delete( - "DELETE FROM #{self.class.quoted_table_name} " + - "WHERE #{connection.quote_column_name(self.class.primary_key)} = #{quoted_id} " + - "AND #{self.class.quoted_locking_column} = #{quote_value(previous_value)}", - "#{self.class.name} Destroy" - ) + table = Arel(self.class.table_name, connection) + affected_rows = table.where( + table[self.class.primary_key].eq(quoted_id).and( + table[self.class.locking_column].eq(quote_value(previous_value)) + ) + ).delete unless affected_rows == 1 raise ActiveRecord::StaleObjectError, "Attempted to delete a stale object" diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb index 657acd6dc0..aa9e9e8fdd 100644 --- a/activerecord/lib/active_record/migration.rb +++ b/activerecord/lib/active_record/migration.rb @@ -103,7 +103,7 @@ module ActiveRecord # # The Rails package has several tools to help create and apply migrations. # - # To generate a new migration, you can use + # To generate a new migration, you can use # script/generate migration MyNewMigration # # where MyNewMigration is the name of your migration. The generator will @@ -121,16 +121,16 @@ module ActiveRecord # def self.up # add_column :tablenames, :fieldname, :string # end - # + # # def self.down # remove_column :tablenames, :fieldname # end # end - # + # # To run migrations against the currently configured database, use # <tt>rake db:migrate</tt>. This will update the database by running all of the # pending migrations, creating the <tt>schema_migrations</tt> table - # (see "About the schema_migrations table" section below) if missing. It will also + # (see "About the schema_migrations table" section below) if missing. It will also # invoke the db:schema:dump task, which will update your db/schema.rb file # to match the structure of your database. # @@ -240,7 +240,7 @@ module ActiveRecord # lower than the current schema version: when migrating up, those # never-applied "interleaved" migrations will be automatically applied, and # when migrating down, never-applied "interleaved" migrations will be skipped. - # + # # == Timestamped Migrations # # By default, Rails generates migrations that look like: @@ -253,7 +253,7 @@ module ActiveRecord # off by setting: # # config.active_record.timestamped_migrations = false - # + # # In environment.rb. # class Migration @@ -338,10 +338,6 @@ module ActiveRecord self.verbose = save end - def connection - ActiveRecord::Base.connection - end - def method_missing(method, *arguments, &block) arg_list = arguments.map(&:inspect) * ', ' @@ -349,7 +345,7 @@ module ActiveRecord unless arguments.empty? || method == :execute arguments[0] = Migrator.proper_table_name(arguments.first) end - connection.send(method, *arguments, &block) + Base.connection.send(method, *arguments, &block) end end end @@ -389,9 +385,9 @@ module ActiveRecord def rollback(migrations_path, steps=1) migrator = self.new(:down, migrations_path) start_index = migrator.migrations.index(migrator.current_migration) - + return unless start_index - + finish = migrator.migrations[start_index + steps] down(migrations_path, finish ? finish.version : 0) end @@ -403,7 +399,7 @@ module ActiveRecord def down(migrations_path, target_version = nil) self.new(:down, migrations_path, target_version).migrate end - + def run(direction, migrations_path, target_version) self.new(direction, migrations_path, target_version).run end @@ -413,7 +409,8 @@ module ActiveRecord end def get_all_versions - Base.connection.select_values("SELECT version FROM #{schema_migrations_table_name}").map(&:to_i).sort + table = Arel(schema_migrations_table_name) + table.project(table['version']).select_values.map(&:to_i).sort end def current_version @@ -434,17 +431,17 @@ module ActiveRecord def initialize(direction, migrations_path, target_version = nil) raise StandardError.new("This database does not yet support migrations") unless Base.connection.supports_migrations? Base.connection.initialize_schema_migrations_table - @direction, @migrations_path, @target_version = direction, migrations_path, target_version + @direction, @migrations_path, @target_version = direction, migrations_path, target_version end def current_version migrated.last || 0 end - + def current_migration migrations.detect { |m| m.version == current_version } end - + def run target = migrations.detect { |m| m.version == @target_version } raise UnknownMigrationVersionError.new(@target_version) if target.nil? @@ -461,14 +458,14 @@ module ActiveRecord if target.nil? && !@target_version.nil? && @target_version > 0 raise UnknownMigrationVersionError.new(@target_version) end - + start = up? ? 0 : (migrations.index(current) || 0) finish = migrations.index(target) || migrations.size - 1 runnable = migrations[start..finish] - + # skip the last migration if we're headed down, but not ALL the way down runnable.pop if down? && !target.nil? - + runnable.each do |migration| Base.logger.info "Migrating to #{migration.name} (#{migration.version})" @@ -496,28 +493,28 @@ module ActiveRecord def migrations @migrations ||= begin files = Dir["#{@migrations_path}/[0-9]*_*.rb"] - + migrations = files.inject([]) do |klasses, file| version, name = file.scan(/([0-9]+)_([_a-z0-9]*).rb/).first - + raise IllegalMigrationNameError.new(file) unless version version = version.to_i - + if klasses.detect { |m| m.version == version } - raise DuplicateMigrationVersionError.new(version) + raise DuplicateMigrationVersionError.new(version) end if klasses.detect { |m| m.name == name.camelize } - raise DuplicateMigrationNameError.new(name.camelize) + raise DuplicateMigrationNameError.new(name.camelize) end - + klasses << returning(MigrationProxy.new) do |migration| migration.name = name.camelize migration.version = version migration.filename = file end end - + migrations = migrations.sort_by(&:version) down? ? migrations.reverse : migrations end @@ -534,15 +531,15 @@ module ActiveRecord private def record_version_state_after_migrating(version) - sm_table = self.class.schema_migrations_table_name + table = Arel(self.class.schema_migrations_table_name) @migrated_versions ||= [] if down? @migrated_versions.delete(version.to_i) - Base.connection.update("DELETE FROM #{sm_table} WHERE version = '#{version}'") + table.where(table["version"].eq(version)).delete else @migrated_versions.push(version.to_i).sort! - Base.connection.insert("INSERT INTO #{sm_table} (version) VALUES ('#{version}')") + table.insert table["version"] => version end end |