New Version

Sync with Latest Instiki Trunk.
Migrate to Rails 1.2.5.
Bump version number.
This commit is contained in:
Jacques Distler 2007-10-15 12:16:54 -05:00
parent de125367b0
commit 207fb1f7f2
120 changed files with 2592 additions and 662 deletions

View file

@ -63,7 +63,7 @@ module ActiveRecord
#{scope_condition_method}
after_destroy :remove_from_list
before_destroy :remove_from_list
before_create :add_to_list_bottom
EOV
end
@ -74,6 +74,7 @@ module ActiveRecord
# lower in the list of all chapters. Likewise, <tt>chapter.first?</tt> would return true if that chapter is
# the first in the list of all chapters.
module InstanceMethods
# Insert the item at the given position (defaults to the top position of 1).
def insert_at(position = 1)
insert_at_position(position)
end
@ -118,8 +119,12 @@ module ActiveRecord
end
end
# Removes the item from the list.
def remove_from_list
decrement_positions_on_lower_items if in_list?
if in_list?
decrement_positions_on_lower_items
update_attribute position_column, nil
end
end
# Increase the position of this item without adjusting the rest of the list.
@ -162,6 +167,7 @@ module ActiveRecord
)
end
# Test if this record is in a list
def in_list?
!send(position_column).nil?
end
@ -178,21 +184,26 @@ module ActiveRecord
# Overwrite this method to define the scope of the list changes
def scope_condition() "1" end
# Returns the bottom position number in the list.
# bottom_position_in_list # => 2
def bottom_position_in_list(except = nil)
item = bottom_item(except)
item ? item.send(position_column) : 0
end
# Returns the bottom item
def bottom_item(except = nil)
conditions = scope_condition
conditions = "#{conditions} AND #{self.class.primary_key} != #{except.id}" if except
acts_as_list_class.find(:first, :conditions => conditions, :order => "#{position_column} DESC")
end
# Forces item to assume the bottom position in the list.
def assume_bottom_position
update_attribute(position_column, bottom_position_in_list(self).to_i + 1)
end
# Forces item to assume the top position in the list.
def assume_top_position
update_attribute(position_column, 1)
end
@ -227,6 +238,7 @@ module ActiveRecord
)
end
# Increments position (<tt>position_column</tt>) of all items in the list.
def increment_positions_on_all_items
acts_as_list_class.update_all(
"#{position_column} = (#{position_column} + 1)", "#{scope_condition}"

View file

@ -70,16 +70,23 @@ module ActiveRecord
nodes
end
# Returns the root node of the tree.
def root
node = self
node = node.parent while node.parent
node
end
# Returns all siblings of the current node.
#
# subchild1.siblings # => [subchild2]
def siblings
self_and_siblings - [self]
end
# Returns all siblings and a reference to the current node.
#
# subchild1.self_and_siblings # => [subchild1, subchild2]
def self_and_siblings
parent ? parent.children : self.class.roots
end

View file

@ -352,7 +352,15 @@ module ActiveRecord
# for post in Post.find(:all, :include => [ :author, :comments ])
#
# That'll add another join along the lines of: LEFT OUTER JOIN comments ON comments.post_id = posts.id. And we'll be down to 1 query.
# But that shouldn't fool you to think that you can pull out huge amounts of data with no performance penalty just because you've reduced
#
# To include a deep hierarchy of associations, using a hash:
#
# for post in Post.find(:all, :include => [ :author, { :comments => { :author => :gravatar } } ])
#
# That'll grab not only all the comments but all their authors and gravatar pictures. You can mix and match
# symbols, arrays and hashes in any combination to describe the associations you want to load.
#
# All of this power shouldn't fool you into thinking that you can pull out huge amounts of data with no performance penalty just because you've reduced
# the number of queries. The database still needs to send all the data to Active Record and it still needs to be processed. So it's no
# catch-all for performance problems, but it's a great way to cut down on the number of queries in a situation as the one described above.
#
@ -734,6 +742,7 @@ module ActiveRecord
deprecated_association_comparison_method(reflection.name, reflection.class_name)
end
# Create the callbacks to update counter cache
if options[:counter_cache]
cache_column = options[:counter_cache] == true ?
"#{self.to_s.underscore.pluralize}_count" :
@ -871,6 +880,12 @@ module ActiveRecord
end
private
# Generate a join table name from two provided tables names.
# The order of names in join name is determined by lexical precedence.
# join_table_name("members", "clubs")
# => "clubs_members"
# join_table_name("members", "special_clubs")
# => "members_special_clubs"
def join_table_name(first_table_name, second_table_name)
if first_table_name < second_table_name
join_table = "#{first_table_name}_#{second_table_name}"
@ -880,7 +895,7 @@ module ActiveRecord
table_name_prefix + join_table + table_name_suffix
end
def association_accessor_methods(reflection, association_proxy_class)
define_method(reflection.name) do |*params|
force_reload = params.first unless params.empty?
@ -901,7 +916,7 @@ module ActiveRecord
define_method("#{reflection.name}=") do |new_value|
association = instance_variable_get("@#{reflection.name}")
if association.nil?
if association.nil? || association.target != new_value
association = association_proxy_class.new(self, reflection)
end
@ -911,10 +926,7 @@ module ActiveRecord
instance_variable_set("@#{reflection.name}", association)
else
instance_variable_set("@#{reflection.name}", nil)
return nil
end
association
end
define_method("set_#{reflection.name}_target") do |target|
@ -981,18 +993,21 @@ module ActiveRecord
after_callback = <<-end_eval
association = instance_variable_get("@#{association_name}")
if association.respond_to?(:loaded?)
if @new_record_before_save
records_to_save = association
else
records_to_save = association.select { |record| record.new_record? }
end
records_to_save = if @new_record_before_save
association
elsif association.respond_to?(:loaded?) && association.loaded?
association.select { |record| record.new_record? }
else
[]
end
if !records_to_save.blank?
records_to_save.each { |record| association.send(:insert_record, record) }
association.send(:construct_sql) # reconstruct the SQL queries now that we know the owner's id
end
end_eval
# Doesn't use after_save as that would save associations added in after_create/after_update twice
after_create(after_callback)
after_update(after_callback)

View file

@ -91,7 +91,11 @@ module ActiveRecord
attributes.collect { |attr| create(attr) }
else
record = build(attributes)
record.save unless @owner.new_record?
if @owner.new_record?
ActiveSupport::Deprecation.warn("Calling .create on a has_many association without saving its owner will not work in rails 2.0, you probably want .build instead")
else
record.save
end
record
end
end

View file

@ -50,7 +50,7 @@ module ActiveRecord
options[:conditions] = options[:conditions].nil? ?
@finder_sql :
@finder_sql + " AND (#{sanitize_sql(options[:conditions])})"
options[:include] = @reflection.options[:include]
options[:include] ||= @reflection.options[:include]
@reflection.klass.count(column_name, options)
end
@ -138,7 +138,7 @@ module ActiveRecord
elsif @reflection.options[:counter_sql]
@reflection.klass.count_by_sql(@counter_sql)
else
@reflection.klass.count(:conditions => @counter_sql)
@reflection.klass.count(:conditions => @counter_sql, :include => @reflection.options[:include])
end
@target = [] and loaded if count == 0

View file

@ -101,6 +101,16 @@ module ActiveRecord
def sum(*args, &block)
calculate(:sum, *args, &block)
end
def count(*args)
column_name, options = @reflection.klass.send(:construct_count_options_from_legacy_args, *args)
if @reflection.options[:uniq]
# This is needed becase 'SELECT count(DISTINCT *)..' is not valid sql statement.
column_name = "#{@reflection.klass.table_name}.#{@reflection.klass.primary_key}" if column_name == :all
options.merge!(:distinct => true)
end
@reflection.klass.send(:with_scope, construct_scope) { @reflection.klass.count(column_name, options) }
end
protected
def method_missing(method, *args, &block)

View file

@ -575,7 +575,7 @@ module ActiveRecord #:nodoc:
# Specifies that the attribute by the name of +attr_name+ should be serialized before saving to the database and unserialized
# after loading from the database. The serialization is done through YAML. If +class_name+ is specified, the serialized
# object must be of that class on retrieval or +SerializationTypeMismatch+ will be raised.
# object must be of that class on retrieval, or nil. Otherwise, +SerializationTypeMismatch+ will be raised.
def serialize(attr_name, class_name = Object)
serialized_attributes[attr_name.to_s] = class_name
end
@ -1188,6 +1188,9 @@ module ActiveRecord #:nodoc:
#
# It's even possible to use all the additional parameters to find. For example, the full interface for find_all_by_amount
# is actually find_all_by_amount(amount, options).
#
# This also enables you to initialize a record if it is not found, such as find_or_initialize_by_amount(amount)
# or find_or_create_by_user_and_password(user, password).
def method_missing(method_id, *arguments)
if match = /^find_(all_by|by)_([_a-zA-Z]\w*)$/.match(method_id.to_s)
finder, deprecated_finder = determine_finder(match), determine_deprecated_finder(match)
@ -1957,7 +1960,7 @@ module ActiveRecord #:nodoc:
def unserialize_attribute(attr_name)
unserialized_object = object_from_yaml(@attributes[attr_name])
if unserialized_object.is_a?(self.class.serialized_attributes[attr_name])
if unserialized_object.is_a?(self.class.serialized_attributes[attr_name]) || unserialized_object.nil?
@attributes[attr_name] = unserialized_object
else
raise SerializationTypeMismatch,
@ -2156,7 +2159,13 @@ module ActiveRecord #:nodoc:
def clone_attribute_value(reader_method, attribute_name)
value = send(reader_method, attribute_name)
value.clone
case value
when nil, Fixnum, true, false
value
else
value.clone
end
rescue TypeError, NoMethodError
value
end

View file

@ -242,8 +242,8 @@ module ActiveRecord
options.assert_valid_keys(CALCULATIONS_OPTIONS)
end
# converts a given key to the value that the database adapter returns as
#
# Converts a given key to the value that the database adapter returns as
# as a usable column name.
# users.id #=> users_id
# sum(id) #=> sum_id
# count(distinct users.id) #=> count_distinct_users_id

View file

@ -24,7 +24,7 @@ module ActiveRecord
when Float, Fixnum, Bignum then value.to_s
# BigDecimals need to be output in a non-normalized form and quoted.
when BigDecimal then value.to_s('F')
when Date then "'#{value.to_s}'"
when Date then "'#{value.to_s(:db)}'"
when Time, DateTime then "'#{quoted_date(value)}'"
else "'#{quote_string(value.to_yaml)}'"
end

View file

@ -320,6 +320,7 @@ begin
decode(data_type, 'NUMBER', data_precision,
'FLOAT', data_precision,
'VARCHAR2', data_length,
'CHAR', data_length,
null) as limit,
decode(data_type, 'NUMBER', data_scale, null) as scale
from all_tab_columns

View file

@ -68,7 +68,7 @@ module ActiveRecord
class SQLiteColumn < Column #:nodoc:
class << self
def string_to_binary(value)
value.gsub(/\0|\%/) do |b|
value.gsub(/\0|\%/n) do |b|
case b
when "\0" then "%00"
when "%" then "%25"
@ -77,7 +77,7 @@ module ActiveRecord
end
def binary_to_string(value)
value.gsub(/%00|%25/) do |b|
value.gsub(/%00|%25/n) do |b|
case b
when "%00" then "\0"
when "%25" then "%"

View file

@ -1,7 +1,7 @@
module ActiveRecord
class Base
class << self
# This method is deprecated in favor of find with the :conditions option.
# DEPRECATION NOTICE: This method is deprecated in favor of find with the :conditions option.
#
# Works like find, but the record matching +id+ must also meet the +conditions+.
# +RecordNotFound+ is raised if no record can be found matching the +id+ or meeting the condition.
@ -12,7 +12,7 @@ module ActiveRecord
end
deprecate :find_on_conditions => "use find(ids, :conditions => conditions)"
# This method is deprecated in favor of find(:first, options).
# DEPRECATION NOTICE: This method is deprecated in favor of find(:first, options).
#
# Returns the object for the first record responding to the conditions in +conditions+,
# such as "group = 'master'". If more than one record is returned from the query, it's the first that'll
@ -24,7 +24,7 @@ module ActiveRecord
end
deprecate :find_first => "use find(:first, ...)"
# This method is deprecated in favor of find(:all, options).
# DEPRECATION NOTICE: This method is deprecated in favor of find(:all, options).
#
# Returns an array of all the objects that could be instantiated from the associated
# table in the database. The +conditions+ can be used to narrow the selection of objects (WHERE-part),

View file

@ -412,7 +412,7 @@ class Fixture #:nodoc:
klass = @class_name.constantize rescue nil
list = @fixture.inject([]) do |fixtures, (key, value)|
col = klass.columns_hash[key] if klass.kind_of?(ActiveRecord::Base)
col = klass.columns_hash[key] if klass.respond_to?(:ancestors) && klass.ancestors.include?(ActiveRecord::Base)
fixtures << ActiveRecord::Base.connection.quote(value, col).gsub('[^\]\\n', "\n").gsub('[^\]\\r', "\r")
end
list * ', '

View file

@ -5,15 +5,6 @@ module ActiveRecord
# Timestamping can be turned off by setting
# <tt>ActiveRecord::Base.record_timestamps = false</tt>
#
# Keep in mind that, via inheritance, you can turn off timestamps on a per
# model basis by setting <tt>record_timestamps</tt> to false in the desired
# models.
#
# class Feed < ActiveRecord::Base
# self.record_timestamps = false
# # ...
# end
#
# Timestamps are in the local timezone by default but can use UTC by setting
# <tt>ActiveRecord::Base.default_timezone = :utc</tt>
module Timestamp

View file

@ -2,7 +2,7 @@ module ActiveRecord
module VERSION #:nodoc:
MAJOR = 1
MINOR = 15
TINY = 3
TINY = 5
STRING = [MAJOR, MINOR, TINY].join('.')
end