Sync with latest Instiki trunk. Changes:

1) Upgrade Rails to 1.2.3
2) Revert RedCloth to previous version (who %#$@ cares?)
3) Preserve the Rails Security fix  to vendor/rails/actionpack/lib/action_controller/caching.rb from Revision 80.
This commit is contained in:
Jacques Distler 2007-03-18 11:56:12 -05:00
parent ff3e03a45a
commit 7adac51d6d
68 changed files with 466 additions and 257 deletions

View file

@ -20,7 +20,13 @@ module ActiveRecord
super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' on the polymorphic object '#{source_reflection.class_name}##{source_reflection.name}'.")
end
end
class HasManyThroughAssociationPointlessSourceTypeError < ActiveRecordError #:nodoc:
def initialize(owner_class_name, reflection, source_reflection)
super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' with a :source_type option if the '#{reflection.through_reflection.class_name}##{source_reflection.name}' is not polymorphic. Try removing :source_type on your association.")
end
end
class HasManyThroughSourceAssociationNotFoundError < ActiveRecordError #:nodoc:
def initialize(reflection)
through_reflection = reflection.through_reflection
@ -529,6 +535,8 @@ module ActiveRecord
# * <tt>:source</tt>: Specifies the source association name used by <tt>has_many :through</tt> queries. Only use it if the name cannot be
# inferred from the association. <tt>has_many :subscribers, :through => :subscriptions</tt> will look for either +:subscribers+ or
# +:subscriber+ on +Subscription+, unless a +:source+ is given.
# * <tt>:source_type</tt>: Specifies type of the source association used by <tt>has_many :through</tt> queries where the source association
# is a polymorphic belongs_to.
# * <tt>:uniq</tt> - if set to true, duplicates will be omitted from the collection. Useful in conjunction with :through.
#
# Option examples:
@ -1087,7 +1095,7 @@ module ActiveRecord
:class_name, :table_name, :foreign_key,
:exclusively_dependent, :dependent,
:select, :conditions, :include, :order, :group, :limit, :offset,
:as, :through, :source,
:as, :through, :source, :source_type,
:uniq,
:finder_sql, :counter_sql,
:before_add, :after_add, :before_remove, :after_remove,
@ -1491,57 +1499,65 @@ module ActiveRecord
case
when reflection.macro == :has_many && reflection.options[:through]
through_conditions = through_reflection.options[:conditions] ? "AND #{interpolate_sql(sanitize_sql(through_reflection.options[:conditions]))}" : ''
if through_reflection.options[:as] # has_many :through against a polymorphic join
polymorphic_foreign_key = through_reflection.options[:as].to_s + '_id'
polymorphic_foreign_type = through_reflection.options[:as].to_s + '_type'
" LEFT OUTER JOIN %s ON (%s.%s = %s.%s AND %s.%s = %s) " % [
table_alias_for(through_reflection.klass.table_name, aliased_join_table_name),
aliased_join_table_name, polymorphic_foreign_key,
parent.aliased_table_name, parent.primary_key,
aliased_join_table_name, polymorphic_foreign_type, klass.quote_value(parent.active_record.base_class.name)] +
" LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [table_name_and_alias,
aliased_table_name, primary_key, aliased_join_table_name, options[:foreign_key] || reflection.klass.to_s.classify.foreign_key
jt_foreign_key = jt_as_extra = jt_source_extra = jt_sti_extra = nil
first_key = second_key = as_extra = nil
if through_reflection.options[:as] # has_many :through against a polymorphic join
jt_foreign_key = through_reflection.options[:as].to_s + '_id'
jt_as_extra = " AND %s.%s = %s" % [
aliased_join_table_name, reflection.active_record.connection.quote_column_name(through_reflection.options[:as].to_s + '_type'),
klass.quote_value(parent.active_record.base_class.name)
]
else
if source_reflection.macro == :has_many && source_reflection.options[:as]
" LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [
table_alias_for(through_reflection.klass.table_name, aliased_join_table_name), aliased_join_table_name,
through_reflection.primary_key_name,
parent.aliased_table_name, parent.primary_key] +
" LEFT OUTER JOIN %s ON %s.%s = %s.%s AND %s.%s = %s " % [
table_name_and_alias,
aliased_table_name, "#{source_reflection.options[:as]}_id",
aliased_join_table_name, options[:foreign_key] || primary_key,
aliased_table_name, "#{source_reflection.options[:as]}_type",
jt_foreign_key = through_reflection.primary_key_name
end
case source_reflection.macro
when :has_many
if source_reflection.options[:as]
first_key = "#{source_reflection.options[:as]}_id"
second_key = options[:foreign_key] || primary_key
as_extra = " AND %s.%s = %s" % [
aliased_table_name, reflection.active_record.connection.quote_column_name("#{source_reflection.options[:as]}_type"),
klass.quote_value(source_reflection.active_record.base_class.name)
]
else
case source_reflection.macro
when :belongs_to
first_key = primary_key
second_key = source_reflection.options[:foreign_key] || klass.to_s.classify.foreign_key
extra = nil
when :has_many
first_key = through_reflection.klass.base_class.to_s.classify.foreign_key
second_key = options[:foreign_key] || primary_key
extra = through_reflection.klass.descends_from_active_record? ? nil :
" AND %s.%s = %s" % [
aliased_join_table_name,
reflection.active_record.connection.quote_column_name(through_reflection.active_record.inheritance_column),
through_reflection.klass.quote_value(through_reflection.klass.name.demodulize)]
end
" LEFT OUTER JOIN %s ON (%s.%s = %s.%s%s) " % [
table_alias_for(through_reflection.klass.table_name, aliased_join_table_name),
aliased_join_table_name, through_reflection.primary_key_name,
parent.aliased_table_name, parent.primary_key, extra] +
" LEFT OUTER JOIN %s ON (%s.%s = %s.%s) " % [
table_name_and_alias,
aliased_table_name, first_key,
aliased_join_table_name, second_key
first_key = through_reflection.klass.base_class.to_s.classify.foreign_key
second_key = options[:foreign_key] || primary_key
end
unless through_reflection.klass.descends_from_active_record?
jt_sti_extra = " AND %s.%s = %s" % [
aliased_join_table_name,
reflection.active_record.connection.quote_column_name(through_reflection.active_record.inheritance_column),
through_reflection.klass.quote_value(through_reflection.klass.name.demodulize)]
end
when :belongs_to
first_key = primary_key
if reflection.options[:source_type]
second_key = source_reflection.association_foreign_key
jt_source_extra = " AND %s.%s = %s" % [
aliased_join_table_name, reflection.active_record.connection.quote_column_name(reflection.source_reflection.options[:foreign_type]),
klass.quote_value(reflection.options[:source_type])
]
else
second_key = source_reflection.options[:foreign_key] || klass.to_s.classify.foreign_key
end
end
" LEFT OUTER JOIN %s ON (%s.%s = %s.%s%s%s%s) " % [
table_alias_for(through_reflection.klass.table_name, aliased_join_table_name),
parent.aliased_table_name, reflection.active_record.connection.quote_column_name(parent.primary_key),
aliased_join_table_name, reflection.active_record.connection.quote_column_name(jt_foreign_key),
jt_as_extra, jt_source_extra, jt_sti_extra
] +
" LEFT OUTER JOIN %s ON (%s.%s = %s.%s%s) " % [
table_name_and_alias,
aliased_table_name, reflection.active_record.connection.quote_column_name(first_key),
aliased_join_table_name, reflection.active_record.connection.quote_column_name(second_key),
as_extra
]
when reflection.macro == :has_many && reflection.options[:as]
" LEFT OUTER JOIN %s ON %s.%s = %s.%s AND %s.%s = %s" % [
@ -1588,6 +1604,7 @@ module ActiveRecord
end
protected
def pluralize(table_name)
ActiveRecord::Base.pluralize_table_names ? table_name.to_s.pluralize : table_name
end

View file

@ -138,7 +138,11 @@ module ActiveRecord
# Construct attributes for :through pointing to owner and associate.
def construct_join_attributes(associate)
construct_owner_attributes(@reflection.through_reflection).merge(@reflection.source_reflection.association_foreign_key => associate.id)
returning construct_owner_attributes(@reflection.through_reflection).merge(@reflection.source_reflection.primary_key_name => associate.id) do |join_attributes|
if @reflection.options[:source_type]
join_attributes.merge!(@reflection.source_reflection.options[:foreign_type] => associate.class.base_class.name.to_s)
end
end
end
# Associate attributes pointing to owner, quoted.
@ -176,6 +180,12 @@ module ActiveRecord
if @reflection.through_reflection.options[:as] || @reflection.source_reflection.macro == :belongs_to
reflection_primary_key = @reflection.klass.primary_key
source_primary_key = @reflection.source_reflection.primary_key_name
if @reflection.options[:source_type]
polymorphic_join = "AND %s.%s = %s" % [
@reflection.through_reflection.table_name, "#{@reflection.source_reflection.options[:foreign_type]}",
@owner.class.quote_value(@reflection.options[:source_type])
]
end
else
reflection_primary_key = @reflection.source_reflection.primary_key_name
source_primary_key = @reflection.klass.primary_key

View file

@ -479,7 +479,7 @@ module ActiveRecord #:nodoc:
# Deletes the record with the given +id+ without instantiating an object first. If an array of ids is provided, all of them
# are deleted.
def delete(id)
delete_all([ "#{primary_key} IN (?)", id ])
delete_all([ "#{connection.quote_column_name(primary_key)} IN (?)", id ])
end
# Destroys the record with the given +id+ by instantiating the object and calling #destroy (all the callbacks are the triggered).
@ -526,12 +526,12 @@ module ActiveRecord #:nodoc:
# for looping over a collection where each element require a number of aggregate values. Like the DiscussionBoard
# that needs to list both the number of posts and comments.
def increment_counter(counter_name, id)
update_all "#{counter_name} = #{counter_name} + 1", "#{primary_key} = #{quote_value(id)}"
update_all "#{connection.quote_column_name(counter_name)} = #{connection.quote_column_name(counter_name)} + 1", "#{connection.quote_column_name(primary_key)} = #{quote_value(id)}"
end
# Works like increment_counter, but decrements instead.
def decrement_counter(counter_name, id)
update_all "#{counter_name} = #{counter_name} - 1", "#{primary_key} = #{quote_value(id)}"
update_all "#{connection.quote_column_name(counter_name)} = #{connection.quote_column_name(counter_name)} - 1", "#{connection.quote_column_name(primary_key)} = #{quote_value(id)}"
end
@ -1020,7 +1020,7 @@ module ActiveRecord #:nodoc:
def find_one(id, options)
conditions = " AND (#{sanitize_sql(options[:conditions])})" if options[:conditions]
options.update :conditions => "#{table_name}.#{primary_key} = #{quote_value(id,columns_hash[primary_key])}#{conditions}"
options.update :conditions => "#{table_name}.#{connection.quote_column_name(primary_key)} = #{quote_value(id,columns_hash[primary_key])}#{conditions}"
# Use find_every(options).first since the primary key condition
# already ensures we have a single record. Using find_initial adds
@ -1035,7 +1035,7 @@ module ActiveRecord #:nodoc:
def find_some(ids, options)
conditions = " AND (#{sanitize_sql(options[:conditions])})" if options[:conditions]
ids_list = ids.map { |id| quote_value(id,columns_hash[primary_key]) }.join(',')
options.update :conditions => "#{table_name}.#{primary_key} IN (#{ids_list})#{conditions}"
options.update :conditions => "#{table_name}.#{connection.quote_column_name(primary_key)} IN (#{ids_list})#{conditions}"
result = find_every(options)
@ -1052,10 +1052,9 @@ module ActiveRecord #:nodoc:
def instantiate(record)
object =
if subclass_name = record[inheritance_column]
# No type given.
if subclass_name.empty?
# No type given.
allocate
else
# Ignore type if no column is present since it was probably
# pulled in from a sloppy join.
@ -1558,7 +1557,7 @@ module ActiveRecord #:nodoc:
unless new_record?
connection.delete <<-end_sql, "#{self.class.name} Destroy"
DELETE FROM #{self.class.table_name}
WHERE #{self.class.primary_key} = #{quoted_id}
WHERE #{connection.quote_column_name(self.class.primary_key)} = #{quoted_id}
end_sql
end
@ -1797,7 +1796,7 @@ module ActiveRecord #:nodoc:
connection.update(
"UPDATE #{self.class.table_name} " +
"SET #{quoted_comma_pair_list(connection, attributes_with_quotes(false))} " +
"WHERE #{self.class.primary_key} = #{quote_value(id)}",
"WHERE #{connection.quote_column_name(self.class.primary_key)} = #{quote_value(id)}",
"#{self.class.name} Update"
)
end

View file

@ -301,18 +301,30 @@ class Fixtures < YAML::Omap
yaml_string << IO.read(subfixture_path)
end
yaml_string << IO.read(yaml_file_path)
begin
yaml = YAML::load(erb_render(yaml_string))
rescue Exception=>boom
raise Fixture::FormatError, "a YAML error occurred parsing #{yaml_file_path}. Please note that YAML must be consistently indented using spaces. Tabs are not allowed. Please have a look at http://www.yaml.org/faq.html\nThe exact error was:\n #{boom.class}: #{boom}"
end
end
if yaml
yaml = yaml.value if yaml.respond_to?(:type_id) and yaml.respond_to?(:value)
yaml.each do |name, data|
unless data
raise Fixture::FormatError, "Bad data for #{@class_name} fixture named #{name} (nil)"
# If the file is an ordered map, extract its children.
yaml_value =
if yaml.respond_to?(:type_id) && yaml.respond_to?(:value)
yaml.value
else
[yaml]
end
yaml_value.each do |fixture|
fixture.each do |name, data|
unless data
raise Fixture::FormatError, "Bad data for #{@class_name} fixture named #{name} (nil)"
end
self[name] = Fixture.new(data, @class_name)
end
self[name] = Fixture.new(data, @class_name)
end
end
elsif File.file?(csv_file_path)

View file

@ -186,8 +186,12 @@ module ActiveRecord
if source_reflection.nil?
raise HasManyThroughSourceAssociationNotFoundError.new(self)
end
if options[:source_type] && source_reflection.options[:polymorphic].nil?
raise HasManyThroughAssociationPointlessSourceTypeError.new(active_record.name, self, source_reflection)
end
if source_reflection.options[:polymorphic]
if source_reflection.options[:polymorphic] && options[:source_type].nil?
raise HasManyThroughAssociationPolymorphicError.new(active_record.name, self, source_reflection)
end
@ -205,7 +209,7 @@ module ActiveRecord
if options[:class_name]
options[:class_name]
elsif through_reflection # get the class_name of the belongs_to association of the through reflection
source_reflection.class_name
options[:source_type] || source_reflection.class_name
else
class_name = name.to_s.camelize
class_name = class_name.singularize if [ :has_many, :has_and_belongs_to_many ].include?(macro)

View file

@ -563,9 +563,9 @@ class Mysql
def scramble41(password, message)
return 0x00.chr if password.nil? or password.empty?
buf = [0x14]
s1 = Digest::SHA1.new(password).digest
s2 = Digest::SHA1.new(s1).digest
x = Digest::SHA1.new(message + s2).digest
s1 = Digest::SHA1.digest(password)
s2 = Digest::SHA1.digest(s1)
x = Digest::SHA1.digest(message + s2)
(0..s1.length - 1).each {|i| buf.push(s1[i] ^ x[i])}
buf.pack("C*")
end
@ -1174,7 +1174,11 @@ class << Mysql
def finalizer(net)
proc {
net.clear
net.write Mysql::COM_QUIT.chr
begin
net.write(Mysql::COM_QUIT.chr)
net.close
rescue # Ignore IOError if socket is already closed.
end
}
end

View file

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