Merge branch 'master' of git@github.com:rails/rails

This commit is contained in:
Jeremy Kemper
2008-07-31 16:35:58 -07:00
74 changed files with 82 additions and 51 deletions

0
actionmailer/README Executable file → Normal file
View File

0
actionmailer/Rakefile Executable file → Normal file
View File

0
actionmailer/lib/action_mailer.rb Executable file → Normal file
View File

0
actionmailer/test/mail_service_test.rb Executable file → Normal file
View File

0
actionpack/lib/action_controller.rb Executable file → Normal file
View File

0
actionpack/lib/action_controller/base.rb Executable file → Normal file
View File

0
actionpack/lib/action_controller/request.rb Executable file → Normal file
View File

0
actionpack/lib/action_controller/request_profiler.rb Executable file → Normal file
View File

0
actionpack/lib/action_controller/response.rb Executable file → Normal file
View File

14
actionpack/lib/action_controller/session/drb_server.rb Normal file → Executable file
View File

@@ -1,8 +1,8 @@
#!/usr/local/bin/ruby -w
# This is a really simple session storage daemon, basically just a hash,
#!/usr/bin/env ruby
# This is a really simple session storage daemon, basically just a hash,
# which is enabled for DRb access.
require 'drb'
session_hash = Hash.new
@@ -14,13 +14,13 @@ class <<session_hash
super(key, value)
end
end
def [](key)
@mutex.synchronize do
super(key)
end
end
def delete(key)
@mutex.synchronize do
super(key)
@@ -29,4 +29,4 @@ class <<session_hash
end
DRb.start_service('druby://127.0.0.1:9192', session_hash)
DRb.thread.join
DRb.thread.join

0
actionpack/lib/action_view/helpers/date_helper.rb Executable file → Normal file
View File

View File

@@ -111,7 +111,7 @@ module ActionView
(100..599).to_a)
AJAX_OPTIONS = Set.new([ :before, :after, :condition, :url,
:asynchronous, :method, :insertion, :position,
:form, :with, :update, :script ]).merge(CALLBACKS)
:form, :with, :update, :script, :type ]).merge(CALLBACKS)
end
# Returns a link to a remote action defined by <tt>options[:url]</tt>

0
actionpack/test/controller/cgi_test.rb Executable file → Normal file
View File

0
actionpack/test/controller/redirect_test.rb Executable file → Normal file
View File

View File

0
actionpack/test/template/date_helper_test.rb Executable file → Normal file
View File

View File

@@ -77,6 +77,8 @@ class PrototypeHelperTest < PrototypeHelperBaseTest
link_to_remote("Remote outauthor", :failure => "alert(request.responseText)", :url => { :action => "whatnot" })
assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot?a=10&amp;b=20', {asynchronous:true, evalScripts:true, onFailure:function(request){alert(request.responseText)}}); return false;\">Remote outauthor</a>),
link_to_remote("Remote outauthor", :failure => "alert(request.responseText)", :url => { :action => "whatnot", :a => '10', :b => '20' })
assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:false, evalScripts:true}); return false;\">Remote outauthor</a>),
link_to_remote("Remote outauthor", :url => { :action => "whatnot" }, :type => :synchronous)
end
def test_link_to_remote_html_options
@@ -429,6 +431,8 @@ Element.update("baz", "\\u003Cp\\u003EThis is a test\\u003C/p\\u003E");
def test_sortable
assert_equal %(Sortable.create("blah", {onUpdate:function(){new Ajax.Request('http://www.example.com/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize("blah")})}});),
@generator.sortable('blah', :url => { :action => "order" })
assert_equal %(Sortable.create("blah", {onUpdate:function(){new Ajax.Request('http://www.example.com/order', {asynchronous:false, evalScripts:true, parameters:Sortable.serialize("blah")})}});),
@generator.sortable('blah', :url => { :action => "order" }, :type => :synchronous)
end
def test_draggable
@@ -439,6 +443,8 @@ Element.update("baz", "\\u003Cp\\u003EThis is a test\\u003C/p\\u003E");
def test_drop_receiving
assert_equal %(Droppables.add("blah", {onDrop:function(element){new Ajax.Request('http://www.example.com/order', {asynchronous:true, evalScripts:true, parameters:'id=' + encodeURIComponent(element.id)})}});),
@generator.drop_receiving('blah', :url => { :action => "order" })
assert_equal %(Droppables.add("blah", {onDrop:function(element){new Ajax.Request('http://www.example.com/order', {asynchronous:false, evalScripts:true, parameters:'id=' + encodeURIComponent(element.id)})}});),
@generator.drop_receiving('blah', :url => { :action => "order" }, :type => :synchronous)
end
def test_collection_first_and_last

0
activemodel/Rakefile Normal file → Executable file
View File

0
activerecord/README Executable file → Normal file
View File

0
activerecord/Rakefile Executable file → Normal file
View File

0
activerecord/lib/active_record.rb Executable file → Normal file
View File

0
activerecord/lib/active_record/associations.rb Executable file → Normal file
View File

View File

View File

10
activerecord/lib/active_record/base.rb Executable file → Normal file
View File

@@ -122,6 +122,10 @@ module ActiveRecord #:nodoc:
class MissingAttributeError < NoMethodError
end
# Raised when unknown attributes are supplied via mass assignment.
class UnknownAttributeError < NoMethodError
end
# Raised when an error occurred while doing a mass assignment to an attribute through the
# <tt>attributes=</tt> method. The exception has an +attribute+ property that is the name of the
# offending attribute.
@@ -2400,7 +2404,11 @@ module ActiveRecord #:nodoc:
attributes = remove_attributes_protected_from_mass_assignment(attributes) if guard_protected_attributes
attributes.each do |k, v|
k.include?("(") ? multi_parameter_attributes << [ k, v ] : send(k + "=", v)
if k.include?("(")
multi_parameter_attributes << [ k, v ]
else
respond_to?(:"#{k}=") ? send(:"#{k}=", v) : raise(UnknownAttributeError, "unknown attribute: #{k}")
end
end
assign_multiparameter_attributes(multi_parameter_attributes)

0
activerecord/lib/active_record/callbacks.rb Executable file → Normal file
View File

View File

@@ -149,6 +149,10 @@ module ActiveRecord
"INSERT INTO #{quote_table_name(table_name)} VALUES(DEFAULT)"
end
def case_sensitive_equality_operator
"="
end
protected
# Returns an array of record hashes with the column names as keys and
# column values as values.

View File

View File

@@ -511,6 +511,10 @@ module ActiveRecord
keys.length == 1 ? [keys.first, nil] : nil
end
def case_sensitive_equality_operator
"= BINARY"
end
private
def connect
@connection.reconnect = true if @connection.respond_to?(:reconnect=)

View File

@@ -182,8 +182,8 @@ module ActiveRecord
def self.extract_value_from_default(default)
case default
# Numeric types
when /\A-?\d+(\.\d*)?\z/
default
when /\A\(?(-?\d+(\.\d*)?\)?)\z/
$1
# Character types
when /\A'(.*)'::(?:character varying|bpchar|text)\z/m
$1

0
activerecord/lib/active_record/fixtures.rb Executable file → Normal file
View File

46
activerecord/lib/active_record/validations.rb Executable file → Normal file
View File

@@ -625,13 +625,25 @@ module ActiveRecord
# class (which has a database table to query from).
finder_class = class_hierarchy.detect { |klass| !klass.abstract_class? }
if value.nil? || (configuration[:case_sensitive] || !finder_class.columns_hash[attr_name.to_s].text?)
condition_sql = "#{record.class.quoted_table_name}.#{attr_name} #{attribute_condition(value)}"
is_text_column = finder_class.columns_hash[attr_name.to_s].text?
if value.nil?
comparison_operator = "IS ?"
else
comparison_operator = "#{connection.case_sensitive_equality_operator} ?"
if is_text_column
value = value.to_s
end
end
sql_attribute = "#{record.class.quoted_table_name}.#{connection.quote_column_name(attr_name)}"
if value.nil? || (configuration[:case_sensitive] || !is_text_column)
condition_sql = "#{sql_attribute} #{comparison_operator}"
condition_params = [value]
else
# sqlite has case sensitive SELECT query, while MySQL/Postgresql don't.
# Hence, this is needed only for sqlite.
condition_sql = "LOWER(#{record.class.quoted_table_name}.#{attr_name}) #{attribute_condition(value)}"
condition_sql = "LOWER(#{sql_attribute}) #{comparison_operator}"
condition_params = [value.downcase]
end
@@ -648,28 +660,10 @@ module ActiveRecord
condition_params << record.send(:id)
end
results = finder_class.with_exclusive_scope do
connection.select_all(
construct_finder_sql(
:select => "#{connection.quote_column_name(attr_name)}",
:from => "#{finder_class.quoted_table_name}",
:conditions => [condition_sql, *condition_params]
)
)
end
unless results.length.zero?
found = true
# As MySQL/Postgres don't have case sensitive SELECT queries, we try to find duplicate
# column in ruby when case sensitive option
if configuration[:case_sensitive] && finder_class.columns_hash[attr_name.to_s].text?
found = results.any? { |a| a[attr_name.to_s] == value.to_s }
end
if found
finder_class.with_exclusive_scope do
if finder_class.exists?([condition_sql, *condition_params])
message = record.errors.generate_message(attr_name, :taken, :default => configuration[:message])
record.errors.add(attr_name, message)
record.errors.add(attr_name, message)
end
end
end

View File

View File

@@ -1007,7 +1007,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
firm.clients.create({ :name => 'Some Client' })
stats = Namespaced::Firm.find(firm.id, {
:select => "#{Namespaced::Firm.table_name}.*, COUNT(#{Namespaced::Client.table_name}.id) AS num_clients",
:select => "#{Namespaced::Firm.table_name}.id, COUNT(#{Namespaced::Client.table_name}.id) AS num_clients",
:joins => :clients,
:group => "#{Namespaced::Firm.table_name}.id"
})

View File

@@ -2,15 +2,18 @@ require "cases/helper"
require 'models/post'
require 'models/person'
require 'models/reader'
require 'models/comment'
class HasManyThroughAssociationsTest < ActiveRecord::TestCase
fixtures :posts, :readers, :people
fixtures :posts, :readers, :people, :comments
def test_associate_existing
assert_queries(2) { posts(:thinking);people(:david) }
posts(:thinking).people
assert_queries(1) do
posts(:thinking).people << people(:david)
posts(:thinking).people << people(:david)
end
assert_queries(1) do

View File

0
activerecord/test/cases/associations_test.rb Executable file → Normal file
View File

0
activerecord/test/cases/attribute_methods_test.rb Executable file → Normal file
View File

8
activerecord/test/cases/base_test.rb Executable file → Normal file
View File

@@ -904,6 +904,14 @@ class BasicsTest < ActiveRecord::TestCase
assert_nil keyboard.id
end
def test_mass_assigning_invalid_attribute
firm = Firm.new
assert_raises(ActiveRecord::UnknownAttributeError) do
firm.attributes = { "id" => 5, "type" => "Client", "i_dont_even_exist" => 20 }
end
end
def test_mass_assignment_protection_on_defaults
firm = Firm.new
firm.attributes = { "id" => 5, "type" => "Client" }

0
activerecord/test/cases/deprecated_finder_test.rb Executable file → Normal file
View File

0
activerecord/test/cases/fixtures_test.rb Executable file → Normal file
View File

0
activerecord/test/cases/inheritance_test.rb Executable file → Normal file
View File

0
activerecord/test/cases/lifecycle_test.rb Executable file → Normal file
View File

0
activerecord/test/cases/readonly_test.rb Executable file → Normal file
View File

0
activerecord/test/cases/unconnected_test.rb Executable file → Normal file
View File

0
activerecord/test/cases/validations_test.rb Executable file → Normal file
View File

0
activerecord/test/models/company.rb Executable file → Normal file
View File

0
activerecord/test/models/reply.rb Executable file → Normal file
View File

0
activerecord/test/models/topic.rb Executable file → Normal file
View File

View File

@@ -1,5 +1,7 @@
*Edge*
* Turn cache_classes on by default [Josh Peek]
* Added configurable eager load paths. Defaults to app/models, app/controllers, and app/helpers [Josh Peek]
* Introduce simple internationalization support. [Ruby i18n team]

0
railties/bin/about Normal file → Executable file
View File

0
railties/bin/console Normal file → Executable file
View File

0
railties/bin/destroy Normal file → Executable file
View File

0
railties/bin/generate Normal file → Executable file
View File

0
railties/bin/performance/benchmarker Normal file → Executable file
View File

0
railties/bin/performance/profiler Normal file → Executable file
View File

0
railties/bin/performance/request Normal file → Executable file
View File

0
railties/bin/plugin Normal file → Executable file
View File

0
railties/bin/process/inspector Normal file → Executable file
View File

0
railties/bin/process/reaper Normal file → Executable file
View File

0
railties/bin/process/spawner Normal file → Executable file
View File

0
railties/bin/runner Normal file → Executable file
View File

0
railties/bin/server Normal file → Executable file
View File

0
railties/configs/apache.conf Executable file → Normal file
View File

View File

@@ -1,4 +1,4 @@
#!/usr/local/bin/ruby
#!/usr/bin/env ruby
#
# You may specify the path to the FastCGI crash log (a log of unhandled
# exceptions which forced the FastCGI instance to exit, great for debugging)

View File

@@ -1,4 +1,4 @@
#!/usr/local/bin/ruby
#!/usr/bin/env ruby
require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
@@ -7,4 +7,4 @@ require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_
require "dispatcher"
ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun)
Dispatcher.dispatch
Dispatcher.dispatch

4
railties/dispatches/gateway.cgi Normal file → Executable file
View File

@@ -1,4 +1,4 @@
#!/usr/local/bin/ruby
#!/usr/bin/env ruby
require 'drb'
@@ -94,4 +94,4 @@ end
$stdout.write output
$stdout.flush
$stdout.close
$stdout.close

View File

@@ -41,6 +41,8 @@ when "mysql"
if config['password'] && include_password
args << "--password=#{config['password']}"
elsif config['password'] && !config['password'].empty?
args << "-p"
end
args << config['database']

4
railties/lib/commands/ncgi/listener Normal file → Executable file
View File

@@ -1,4 +1,4 @@
#!/usr/local/bin/ruby
#!/usr/bin/env ruby
require 'stringio'
require 'fileutils'
@@ -83,4 +83,4 @@ end
socket_path = ARGV.shift
timeout = (ARGV.shift || 90).to_i
Listener.new(timeout, socket_path)
Listener.new(timeout, socket_path)

4
railties/lib/commands/ncgi/tracker Normal file → Executable file
View File

@@ -1,4 +1,4 @@
#!/usr/local/bin/ruby
#!/usr/bin/env ruby
require 'drb'
require 'thread'
@@ -66,4 +66,4 @@ end
socket_path = ARGV.shift
instances = ARGV.shift.to_i
t = Tracker.new(instances, socket_path)
t.background(ARGV.first ? ARGV.shift.to_i : 90)
t.background(ARGV.first ? ARGV.shift.to_i : 90)

View File

@@ -904,7 +904,7 @@ Run `rake gems:install` to install the missing gems.
end
def default_cache_classes
false
true
end
def default_whiny_nils