mirror of
https://github.com/github/rails.git
synced 2026-04-26 03:00:59 -04:00
r1603@asus: jeremy | 2005-07-02 14:38:52 -0700
Faster MysqlAdapter#select. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1622 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
@@ -16,7 +16,7 @@ def require_library_or_gem(library_name)
|
||||
raise cannot_require
|
||||
end
|
||||
# 2. Rubygems is installed and loaded. Try to load the library again
|
||||
begin
|
||||
begin
|
||||
require library_name
|
||||
rescue LoadError => gem_not_installed
|
||||
raise cannot_require
|
||||
@@ -32,7 +32,7 @@ module ActiveRecord
|
||||
@config, @adapter_method = config, adapter_method
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# The class -> [adapter_method, config] map
|
||||
@@defined_connections = {}
|
||||
|
||||
@@ -92,32 +92,32 @@ module ActiveRecord
|
||||
# for (not necessarily the current class).
|
||||
def self.retrieve_connection #:nodoc:
|
||||
klass = self
|
||||
until klass == ActiveRecord::Base.superclass
|
||||
Thread.current['active_connections'] ||= {}
|
||||
if Thread.current['active_connections'][klass]
|
||||
return Thread.current['active_connections'][klass]
|
||||
elsif @@defined_connections[klass]
|
||||
klass.connection = @@defined_connections[klass]
|
||||
ar_super = ActiveRecord::Base.superclass
|
||||
until klass == ar_super
|
||||
if conn = (Thread.current['active_connections'] ||= {})[klass]
|
||||
return conn
|
||||
elsif conn = @@defined_connections[klass]
|
||||
klass.connection = conn
|
||||
return self.connection
|
||||
end
|
||||
klass = klass.superclass
|
||||
end
|
||||
raise ConnectionNotEstablished
|
||||
end
|
||||
|
||||
|
||||
# Returns true if a connection that's accessible to this class have already been opened.
|
||||
def self.connected?
|
||||
klass = self
|
||||
until klass == ActiveRecord::Base.superclass
|
||||
if Thread.current['active_connections'].is_a?(Hash) && Thread.current['active_connections'][klass]
|
||||
return true
|
||||
return true
|
||||
else
|
||||
klass = klass.superclass
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
# Remove the connection for this class. This will close the active
|
||||
# connection and the defined connection (if they exist). The result
|
||||
# can be used as argument for establish_connection, for easy
|
||||
@@ -129,7 +129,7 @@ module ActiveRecord
|
||||
Thread.current['active_connections'][klass] = nil
|
||||
conn.config if conn
|
||||
end
|
||||
|
||||
|
||||
# Set the connection for the class.
|
||||
def self.connection=(spec)
|
||||
raise ConnectionNotEstablished unless spec
|
||||
@@ -147,17 +147,15 @@ module ActiveRecord
|
||||
module ConnectionAdapters # :nodoc:
|
||||
class Column # :nodoc:
|
||||
attr_reader :name, :default, :type, :limit
|
||||
attr_accessor :primary
|
||||
# The name should contain the name of the column, such as "name" in "name varchar(250)"
|
||||
# The default should contain the type-casted default of the column, such as 1 in "count int(11) DEFAULT 1"
|
||||
# The type parameter should either contain :integer, :float, :datetime, :date, :text, or :string
|
||||
# The sql_type is just used for extracting the limit, such as 10 in "varchar(10)"
|
||||
def initialize(name, default, sql_type = nil)
|
||||
@name, @default, @type = name, default, simplified_type(sql_type)
|
||||
@name, @default, @type = name, type_cast(default), simplified_type(sql_type)
|
||||
@limit = extract_limit(sql_type) unless sql_type.nil?
|
||||
end
|
||||
|
||||
def default
|
||||
type_cast(@default)
|
||||
@primary = nil
|
||||
end
|
||||
|
||||
def klass
|
||||
@@ -173,7 +171,7 @@ module ActiveRecord
|
||||
when :boolean then Object
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def type_cast(value)
|
||||
if value.nil? then return nil end
|
||||
case type
|
||||
@@ -190,18 +188,18 @@ module ActiveRecord
|
||||
else value
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def human_name
|
||||
Base.human_attribute_name(@name)
|
||||
end
|
||||
|
||||
|
||||
def string_to_binary(value)
|
||||
value
|
||||
end
|
||||
end
|
||||
|
||||
def binary_to_string(value)
|
||||
value
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def string_to_date(string)
|
||||
@@ -210,7 +208,7 @@ module ActiveRecord
|
||||
# treat 0000-00-00 as nil
|
||||
Date.new(date_array[0], date_array[1], date_array[2]) rescue nil
|
||||
end
|
||||
|
||||
|
||||
def string_to_time(string)
|
||||
return string unless string.is_a?(String)
|
||||
time_array = ParseDate.parsedate(string.to_s).compact
|
||||
@@ -224,12 +222,12 @@ module ActiveRecord
|
||||
# pad the resulting array with dummy date information
|
||||
time_array[0] = 2000; time_array[1] = 1; time_array[2] = 1;
|
||||
Time.send(Base.default_timezone, *time_array) rescue nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def extract_limit(sql_type)
|
||||
$1.to_i if sql_type =~ /\((.*)\)/
|
||||
end
|
||||
|
||||
|
||||
def simplified_type(field_type)
|
||||
case field_type
|
||||
when /int/i
|
||||
@@ -271,7 +269,7 @@ module ActiveRecord
|
||||
|
||||
# Returns an array of record hashes with the column names as a keys and fields as values.
|
||||
def select_all(sql, name = nil) end
|
||||
|
||||
|
||||
# Returns a record hash with the column names as a keys and fields as values.
|
||||
def select_one(sql, name = nil) end
|
||||
|
||||
@@ -310,8 +308,8 @@ module ActiveRecord
|
||||
|
||||
# Begins the transaction (and turns off auto-committing).
|
||||
def begin_db_transaction() end
|
||||
|
||||
# Commits the transaction (and turns on auto-committing).
|
||||
|
||||
# Commits the transaction (and turns on auto-committing).
|
||||
def commit_db_transaction() end
|
||||
|
||||
# Rolls back the transaction (and turns on auto-committing). Must be done if the transaction block
|
||||
@@ -320,7 +318,7 @@ module ActiveRecord
|
||||
|
||||
def quote(value, column = nil)
|
||||
case value
|
||||
when String
|
||||
when String
|
||||
if column && column.type == :binary
|
||||
"'#{quote_string(column.string_to_binary(value))}'" # ' (for ruby-mode)
|
||||
else
|
||||
@@ -330,7 +328,7 @@ module ActiveRecord
|
||||
when TrueClass then (column && column.type == :boolean ? "'t'" : "1")
|
||||
when FalseClass then (column && column.type == :boolean ? "'f'" : "0")
|
||||
when Float, Fixnum, Bignum then value.to_s
|
||||
when Date then "'#{value.to_s}'"
|
||||
when Date then "'#{value.to_s}'"
|
||||
when Time, DateTime then "'#{value.strftime("%Y-%m-%d %H:%M:%S")}'"
|
||||
else "'#{quote_string(value.to_yaml)}'"
|
||||
end
|
||||
@@ -356,7 +354,7 @@ module ActiveRecord
|
||||
return unless options
|
||||
add_limit_offset!(sql, options)
|
||||
end
|
||||
|
||||
|
||||
def add_limit_offset!(sql, options)
|
||||
return if options[:limit].nil?
|
||||
sql << " LIMIT #{options[:limit]}"
|
||||
@@ -399,7 +397,7 @@ module ActiveRecord
|
||||
def log(sql, name, connection = nil)
|
||||
connection ||= @connection
|
||||
begin
|
||||
if @logger.nil? || @logger.level > Logger::INFO
|
||||
if !@logger || @logger.level > Logger::INFO
|
||||
yield connection
|
||||
elsif block_given?
|
||||
result = nil
|
||||
@@ -418,11 +416,11 @@ module ActiveRecord
|
||||
end
|
||||
|
||||
def log_info(sql, name, runtime)
|
||||
if @logger.nil? then return end
|
||||
return unless @logger
|
||||
|
||||
@logger.info(
|
||||
format_log_entry(
|
||||
"#{name.nil? ? "SQL" : name} (#{sprintf("%f", runtime)})",
|
||||
"#{name.nil? ? "SQL" : name} (#{sprintf("%f", runtime)})",
|
||||
sql.gsub(/ +/, " ")
|
||||
)
|
||||
)
|
||||
@@ -435,7 +433,7 @@ module ActiveRecord
|
||||
else
|
||||
@@row_even = true; caller_color = "1;36"; message_color = "4;35"; dump_color = "0;37"
|
||||
end
|
||||
|
||||
|
||||
log_entry = " \e[#{message_color}m#{message}\e[m"
|
||||
log_entry << " \e[#{dump_color}m%s\e[m" % dump if dump.kind_of?(String) && !dump.nil?
|
||||
log_entry << " \e[#{dump_color}m%p\e[m" % dump if !dump.kind_of?(String) && !dump.nil?
|
||||
@@ -448,7 +446,7 @@ module ActiveRecord
|
||||
|
||||
class TableDefinition
|
||||
attr_accessor :columns
|
||||
|
||||
|
||||
def initialize
|
||||
@columns = []
|
||||
end
|
||||
|
||||
@@ -79,14 +79,16 @@ begin
|
||||
@connection.set_auto_commit_on
|
||||
end
|
||||
|
||||
def quote_column_name(name) name; end
|
||||
def quote_column_name(column_name)
|
||||
column_name
|
||||
end
|
||||
|
||||
def adapter_name()
|
||||
'DB2'
|
||||
end
|
||||
|
||||
def quote_string(s)
|
||||
s.gsub(/'/, "''") # ' (for ruby-mode)
|
||||
def quote_string(string)
|
||||
string.gsub(/'/, "''") # ' (for ruby-mode)
|
||||
end
|
||||
|
||||
def add_limit_with_offset!(sql, limit, offset)
|
||||
|
||||
@@ -108,20 +108,26 @@ module ActiveRecord
|
||||
|
||||
def insert(sql, name = nil, pk = nil, id_value = nil)
|
||||
execute(sql, name = nil)
|
||||
return id_value || @connection.insert_id
|
||||
id_value || @connection.insert_id
|
||||
end
|
||||
|
||||
def execute(sql, name = nil)
|
||||
begin
|
||||
return log(sql, name, @connection) { |connection| connection.query(sql) }
|
||||
rescue ActiveRecord::StatementInvalid => exception
|
||||
if LOST_CONNECTION_ERROR_MESSAGES.any? { |msg| exception.message.split(":").first =~ /^#{msg}/ }
|
||||
@connection.real_connect(*@connection_options)
|
||||
@logger.info("Retrying invalid statement with reopened connection") if @logger
|
||||
return log(sql, name, @connection) { |connection| connection.query(sql) }
|
||||
def execute(sql, name = nil, retries = 2)
|
||||
unless @logger
|
||||
@connection.query(sql)
|
||||
else
|
||||
log(sql, name) { @connection.query(sql) }
|
||||
end
|
||||
rescue ActiveRecord::StatementInvalid => exception
|
||||
if LOST_CONNECTION_ERROR_MESSAGES.any? { |msg| exception.message.split(":").first =~ /^#{msg}/ }
|
||||
@connection.real_connect(*@connection_options)
|
||||
@logger.info("Retrying invalid statement with reopened connection") if @logger
|
||||
unless @logger
|
||||
@connection.query(sql)
|
||||
else
|
||||
raise
|
||||
log(sql, name) { @connection.query(sql) }
|
||||
end
|
||||
else
|
||||
raise
|
||||
end
|
||||
end
|
||||
|
||||
@@ -134,36 +140,30 @@ module ActiveRecord
|
||||
|
||||
|
||||
def begin_db_transaction
|
||||
begin
|
||||
execute "BEGIN"
|
||||
rescue Exception
|
||||
# Transactions aren't supported
|
||||
end
|
||||
execute "BEGIN"
|
||||
rescue Exception
|
||||
# Transactions aren't supported
|
||||
end
|
||||
|
||||
def commit_db_transaction
|
||||
begin
|
||||
execute "COMMIT"
|
||||
rescue Exception
|
||||
# Transactions aren't supported
|
||||
end
|
||||
execute "COMMIT"
|
||||
rescue Exception
|
||||
# Transactions aren't supported
|
||||
end
|
||||
|
||||
def rollback_db_transaction
|
||||
begin
|
||||
execute "ROLLBACK"
|
||||
rescue Exception
|
||||
# Transactions aren't supported
|
||||
end
|
||||
execute "ROLLBACK"
|
||||
rescue Exception
|
||||
# Transactions aren't supported
|
||||
end
|
||||
|
||||
|
||||
def quote_column_name(name)
|
||||
return "`#{name}`"
|
||||
"`#{name}`"
|
||||
end
|
||||
|
||||
def quote_string(s)
|
||||
Mysql::quote(s)
|
||||
def quote_string(string)
|
||||
Mysql::quote(string)
|
||||
end
|
||||
|
||||
|
||||
@@ -174,12 +174,12 @@ module ActiveRecord
|
||||
end
|
||||
|
||||
def add_limit_offset!(sql, options)
|
||||
return if options[:limit].nil?
|
||||
|
||||
if options[:offset].blank?
|
||||
sql << " LIMIT #{options[:limit]}"
|
||||
else
|
||||
sql << " LIMIT #{options[:offset]}, #{options[:limit]}"
|
||||
unless options[:limit].blank?
|
||||
unless options[:offset].blank?
|
||||
sql << " LIMIT #{options[:offset]}, #{options[:limit]}"
|
||||
else
|
||||
sql << " LIMIT #{options[:limit]}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -203,14 +203,15 @@ module ActiveRecord
|
||||
|
||||
private
|
||||
def select(sql, name = nil)
|
||||
result = nil
|
||||
@connection.query_with_result = true
|
||||
result = execute(sql, name)
|
||||
rows = []
|
||||
all_fields_initialized = result.fetch_fields.inject({}) { |all_fields, f| all_fields[f.name] = nil; all_fields }
|
||||
result.each_hash { |row| rows << all_fields_initialized.dup.update(row) }
|
||||
#all_fields_initialized = result.fetch_fields.inject({}) { |all_fields, f| all_fields[f.name] = nil; all_fields }
|
||||
#result.each_hash { |row| rows << all_fields_initialized.dup.update(row) }
|
||||
result.each_hash { |row| rows << row }
|
||||
result.free
|
||||
rows
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -99,8 +99,8 @@ begin
|
||||
# * <tt>:password</tt> -- Defaults to nothing
|
||||
# * <tt>:host</tt> -- Defaults to localhost
|
||||
class OCIAdapter < AbstractAdapter
|
||||
def quote_string(s)
|
||||
s.gsub /'/, "''"
|
||||
def quote_string(string)
|
||||
string.gsub(/'/, "''")
|
||||
end
|
||||
|
||||
def quote(value, column = nil)
|
||||
|
||||
@@ -159,7 +159,7 @@ module ActiveRecord
|
||||
end
|
||||
|
||||
def quote_column_name(name)
|
||||
return "'#{name}'"
|
||||
"'#{name}'"
|
||||
end
|
||||
|
||||
def adapter_name()
|
||||
|
||||
@@ -300,8 +300,8 @@ module ActiveRecord
|
||||
end
|
||||
end
|
||||
|
||||
def quote_string(s)
|
||||
s.gsub(/\'/, "''")
|
||||
def quote_string(string)
|
||||
string.gsub(/\'/, "''")
|
||||
end
|
||||
|
||||
def quote_column_name(name)
|
||||
@@ -363,7 +363,7 @@ module ActiveRecord
|
||||
end
|
||||
|
||||
def has_identity_column(table_name)
|
||||
return get_identity_column(table_name) != nil
|
||||
!get_identity_column(table_name).nil?
|
||||
end
|
||||
|
||||
def get_identity_column(table_name)
|
||||
@@ -377,7 +377,7 @@ module ActiveRecord
|
||||
end
|
||||
|
||||
def query_contains_identity_column(sql, col)
|
||||
return sql =~ /\[#{col}\]/
|
||||
sql =~ /\[#{col}\]/
|
||||
end
|
||||
|
||||
def change_order_direction(order)
|
||||
|
||||
Reference in New Issue
Block a user