aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2007-10-16 05:06:33 +0000
committerJeremy Kemper <jeremy@bitsweat.net>2007-10-16 05:06:33 +0000
commit9b6207c3d0596599078b4171caa71b6e7c49ebc9 (patch)
treeee21d9d91d2081f6634e0ebac2c67818c2a846aa /activerecord/lib/active_record
parente7ed4c93542f323aa135b17d4e31d13c4a59febb (diff)
downloadrails-9b6207c3d0596599078b4171caa71b6e7c49ebc9.tar.gz
rails-9b6207c3d0596599078b4171caa71b6e7c49ebc9.tar.bz2
rails-9b6207c3d0596599078b4171caa71b6e7c49ebc9.zip
Quote table names. Defaults to column quoting. Closes #4593.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7932 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activerecord/lib/active_record')
-rwxr-xr-xactiverecord/lib/active_record/base.rb26
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/quoting.rb12
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb26
-rwxr-xr-xactiverecord/lib/active_record/connection_adapters/abstract_adapter.rb6
-rwxr-xr-xactiverecord/lib/active_record/connection_adapters/mysql_adapter.rb32
-rwxr-xr-xactiverecord/lib/active_record/fixtures.rb2
7 files changed, 65 insertions, 43 deletions
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 67a0299490..4eb99551cd 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -531,7 +531,7 @@ module ActiveRecord #:nodoc:
# calling the destroy method). Example:
# Post.delete_all "person_id = 5 AND (category = 'Something' OR category = 'Else')"
def delete_all(conditions = nil)
- sql = "DELETE FROM #{table_name} "
+ sql = "DELETE FROM #{quoted_table_name} "
add_conditions!(sql, conditions, scope(:find))
connection.delete(sql, "#{name} Delete all")
end
@@ -1033,7 +1033,7 @@ module ActiveRecord #:nodoc:
def find_one(id, options)
conditions = " AND (#{sanitize_sql(options[:conditions])})" if options[:conditions]
- options.update :conditions => "#{table_name}.#{connection.quote_column_name(primary_key)} = #{quote_value(id,columns_hash[primary_key])}#{conditions}"
+ options.update :conditions => "#{quoted_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
@@ -1048,7 +1048,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}.#{connection.quote_column_name(primary_key)} IN (#{ids_list})#{conditions}"
+ options.update :conditions => "#{quoted_table_name}.#{connection.quote_column_name(primary_key)} IN (#{ids_list})#{conditions}"
result = find_every(options)
@@ -1126,8 +1126,8 @@ module ActiveRecord #:nodoc:
def construct_finder_sql(options)
scope = scope(:find)
- sql = "SELECT #{(scope && scope[:select]) || options[:select] || (options[:joins] && table_name + '.*') || '*'} "
- sql << "FROM #{(scope && scope[:from]) || options[:from] || table_name} "
+ sql = "SELECT #{(scope && scope[:select]) || options[:select] || (options[:joins] && quoted_table_name + '.*') || '*'} "
+ sql << "FROM #{(scope && scope[:from]) || options[:from] || quoted_table_name} "
add_joins!(sql, options, scope)
add_conditions!(sql, options[:conditions], scope)
@@ -1220,8 +1220,8 @@ module ActiveRecord #:nodoc:
def type_condition
quoted_inheritance_column = connection.quote_column_name(inheritance_column)
- type_condition = subclasses.inject("#{table_name}.#{quoted_inheritance_column} = '#{name.demodulize}' ") do |condition, subclass|
- condition << "OR #{table_name}.#{quoted_inheritance_column} = '#{subclass.name.demodulize}' "
+ type_condition = subclasses.inject("#{quoted_table_name}.#{quoted_inheritance_column} = '#{name.demodulize}' ") do |condition, subclass|
+ condition << "OR #{quoted_table_name}.#{quoted_inheritance_column} = '#{subclass.name.demodulize}' "
end
" (#{type_condition}) "
@@ -1572,7 +1572,7 @@ module ActiveRecord #:nodoc:
# # => "age BETWEEN 13 AND 18"
def sanitize_sql_hash_for_conditions(attrs)
conditions = attrs.map do |attr, value|
- "#{table_name}.#{connection.quote_column_name(attr)} #{attribute_condition(value)}"
+ "#{quoted_table_name}.#{connection.quote_column_name(attr)} #{attribute_condition(value)}"
end.join(' AND ')
replace_bind_variables(conditions, expand_range_bind_variables(attrs.values))
@@ -1742,7 +1742,7 @@ module ActiveRecord #:nodoc:
def destroy
unless new_record?
connection.delete <<-end_sql, "#{self.class.name} Destroy"
- DELETE FROM #{self.class.table_name}
+ DELETE FROM #{self.class.quoted_table_name}
WHERE #{connection.quote_column_name(self.class.primary_key)} = #{quoted_id}
end_sql
end
@@ -1986,7 +1986,7 @@ module ActiveRecord #:nodoc:
quoted_attributes = attributes_with_quotes(false, false)
return 0 if quoted_attributes.empty?
connection.update(
- "UPDATE #{self.class.table_name} " +
+ "UPDATE #{self.class.quoted_table_name} " +
"SET #{quoted_comma_pair_list(connection, quoted_attributes)} " +
"WHERE #{connection.quote_column_name(self.class.primary_key)} = #{quote_value(id)}",
"#{self.class.name} Update"
@@ -2005,7 +2005,7 @@ module ActiveRecord #:nodoc:
statement = if quoted_attributes.empty?
connection.empty_insert_statement(self.class.table_name)
else
- "INSERT INTO #{self.class.table_name} " +
+ "INSERT INTO #{self.class.quoted_table_name} " +
"(#{quoted_column_names.join(', ')}) " +
"VALUES(#{quoted_attributes.values.join(', ')})"
end
@@ -2180,6 +2180,10 @@ module ActiveRecord #:nodoc:
end
end
+ def self.quoted_table_name
+ self.connection.quote_table_name(self.table_name)
+ end
+
def quote_columns(quoter, hash)
hash.inject({}) do |quoted, (name, value)|
quoted[quoter.quote_column_name(name)] = value
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
index 341b104f06..066baaba45 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -136,11 +136,11 @@ module ActiveRecord
# Inserts the given fixture into the table. Overridden in adapters that require
# something beyond a simple insert (eg. Oracle).
def insert_fixture(fixture, table_name)
- execute "INSERT INTO #{table_name} (#{fixture.key_list}) VALUES (#{fixture.value_list})", 'Fixture Insert'
+ execute "INSERT INTO #{quote_table_name(table_name)} (#{fixture.key_list}) VALUES (#{fixture.value_list})", 'Fixture Insert'
end
def empty_insert_statement(table_name)
- "INSERT INTO #{table_name} VALUES(DEFAULT)"
+ "INSERT INTO #{quote_table_name(table_name)} VALUES(DEFAULT)"
end
protected
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
index b3b3d70359..3a7bf35248 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
@@ -39,10 +39,14 @@ module ActiveRecord
s.gsub(/\\/, '\&\&').gsub(/'/, "''") # ' (for ruby-mode)
end
- # Returns a quoted form of the column name. This is highly adapter
- # specific.
- def quote_column_name(name)
- name
+ # Quotes the column name. Defaults to no quoting.
+ def quote_column_name(column_name)
+ column_name
+ end
+
+ # Quotes the table name. Defaults to column name quoting.
+ def quote_table_name(table_name)
+ quote_column_name(table_name)
end
def quoted_true
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
index f27b2287f4..d4fcded32a 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -87,39 +87,39 @@ module ActiveRecord
# )
#
# See also TableDefinition#column for details on how to create columns.
- def create_table(name, options = {})
+ def create_table(table_name, options = {})
table_definition = TableDefinition.new(self)
table_definition.primary_key(options[:primary_key] || "id") unless options[:id] == false
yield table_definition
if options[:force]
- drop_table(name, options) rescue nil
+ drop_table(table_name, options) rescue nil
end
create_sql = "CREATE#{' TEMPORARY' if options[:temporary]} TABLE "
- create_sql << "#{name} ("
+ create_sql << "#{quote_table_name(table_name)} ("
create_sql << table_definition.to_sql
create_sql << ") #{options[:options]}"
execute create_sql
end
-
+
# Renames a table.
# ===== Example
# rename_table('octopuses', 'octopi')
- def rename_table(name, new_name)
+ def rename_table(table_name, new_name)
raise NotImplementedError, "rename_table is not implemented"
end
# Drops a table from the database.
- def drop_table(name, options = {})
- execute "DROP TABLE #{name}"
+ def drop_table(table_name, options = {})
+ execute "DROP TABLE #{quote_table_name(table_name)}"
end
# Adds a new column to the named table.
# See TableDefinition#column for details of the options you can use.
def add_column(table_name, column_name, type, options = {})
- add_column_sql = "ALTER TABLE #{table_name} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
+ add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
add_column_options!(add_column_sql, options)
execute(add_column_sql)
end
@@ -128,7 +128,7 @@ module ActiveRecord
# ===== Examples
# remove_column(:suppliers, :qualification)
def remove_column(table_name, column_name)
- execute "ALTER TABLE #{table_name} DROP #{quote_column_name(column_name)}"
+ execute "ALTER TABLE #{quote_table_name(table_name)} DROP #{quote_column_name(column_name)}"
end
# Changes the column's definition according to the new options.
@@ -194,7 +194,7 @@ module ActiveRecord
index_type = options
end
quoted_column_names = column_names.map { |e| quote_column_name(e) }.join(", ")
- execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{table_name} (#{quoted_column_names})"
+ execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{quoted_column_names})"
end
# Remove the given index from the table.
@@ -234,8 +234,8 @@ module ActiveRecord
# The migrations module handles this automatically.
def initialize_schema_information
begin
- execute "CREATE TABLE #{ActiveRecord::Migrator.schema_info_table_name} (version #{type_to_sql(:integer)})"
- execute "INSERT INTO #{ActiveRecord::Migrator.schema_info_table_name} (version) VALUES(0)"
+ execute "CREATE TABLE #{quote_table_name(ActiveRecord::Migrator.schema_info_table_name)} (version #{type_to_sql(:integer)})"
+ execute "INSERT INTO #{quote_table_name(ActiveRecord::Migrator.schema_info_table_name)} (version) VALUES(0)"
rescue ActiveRecord::StatementInvalid
# Schema has been initialized
end
@@ -244,7 +244,7 @@ module ActiveRecord
def dump_schema_information #:nodoc:
begin
if (current_schema = ActiveRecord::Migrator.current_version) > 0
- return "INSERT INTO #{ActiveRecord::Migrator.schema_info_table_name} (version) VALUES (#{current_schema})"
+ return "INSERT INTO #{quote_table_name(ActiveRecord::Migrator.schema_info_table_name)} (version) VALUES (#{current_schema})"
end
rescue ActiveRecord::StatementInvalid
# No Schema Info
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index 18de0e0739..0741a47cc2 100755
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -63,6 +63,12 @@ module ActiveRecord
rt
end
+ # QUOTING ==================================================
+
+ # Override to return the quoted table name if the database needs it
+ def quote_table_name(name)
+ name
+ end
# CONNECTION MANAGEMENT ====================================
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index 62cfc345a3..6ef7bb5b1a 100755
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -208,6 +208,10 @@ module ActiveRecord
"`#{name}`"
end
+ def quote_table_name(name) #:nodoc:
+ quote_column_name(name)
+ end
+
def quote_string(string) #:nodoc:
@connection.quote(string)
end
@@ -322,7 +326,7 @@ module ActiveRecord
select_all(sql).inject("") do |structure, table|
table.delete('Table_type')
- structure += select_one("SHOW CREATE TABLE #{table.to_a.first.last}")["Create Table"] + ";\n\n"
+ structure += select_one("SHOW CREATE TABLE #{quote_table_name(table.to_a.first.last)}")["Create Table"] + ";\n\n"
end
end
@@ -370,10 +374,14 @@ module ActiveRecord
tables
end
+ def drop_table(table_name, options = {})
+ super(table_name, options)
+ end
+
def indexes(table_name, name = nil)#:nodoc:
indexes = []
current_index = nil
- execute("SHOW KEYS FROM #{table_name}", name).each do |row|
+ execute("SHOW KEYS FROM #{quote_table_name(table_name)}", name).each do |row|
if current_index != row[2]
next if row[2] == "PRIMARY" # skip the primary key
current_index = row[2]
@@ -386,24 +394,24 @@ module ActiveRecord
end
def columns(table_name, name = nil)#:nodoc:
- sql = "SHOW FIELDS FROM #{table_name}"
+ sql = "SHOW FIELDS FROM #{quote_table_name(table_name)}"
columns = []
execute(sql, name).each { |field| columns << MysqlColumn.new(field[0], field[4], field[1], field[2] == "YES") }
columns
end
- def create_table(name, options = {}) #:nodoc:
- super(name, {:options => "ENGINE=InnoDB"}.merge(options))
+ def create_table(table_name, options = {}) #:nodoc:
+ super(table_name, options.reverse_merge(:options => "ENGINE=InnoDB"))
end
- def rename_table(name, new_name)
- execute "RENAME TABLE #{name} TO #{new_name}"
+ def rename_table(table_name, new_name)
+ execute "RENAME TABLE #{quote_table_name(table_name)} TO #{quote_table_name(new_name)}"
end
def change_column_default(table_name, column_name, default) #:nodoc:
- current_type = select_one("SHOW COLUMNS FROM #{table_name} LIKE '#{column_name}'")["Type"]
+ current_type = select_one("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE '#{column_name}'")["Type"]
- execute("ALTER TABLE #{table_name} CHANGE #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{current_type} DEFAULT #{quote(default)}")
+ execute("ALTER TABLE #{quote_table_name(table_name)} CHANGE #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{current_type} DEFAULT #{quote(default)}")
end
def change_column(table_name, column_name, type, options = {}) #:nodoc:
@@ -415,14 +423,14 @@ module ActiveRecord
end
end
- change_column_sql = "ALTER TABLE #{table_name} CHANGE #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
+ change_column_sql = "ALTER TABLE #{quote_table_name(table_name)} CHANGE #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
add_column_options!(change_column_sql, options)
execute(change_column_sql)
end
def rename_column(table_name, column_name, new_column_name) #:nodoc:
- current_type = select_one("SHOW COLUMNS FROM #{table_name} LIKE '#{column_name}'")["Type"]
- execute "ALTER TABLE #{table_name} CHANGE #{quote_column_name(column_name)} #{quote_column_name(new_column_name)} #{current_type}"
+ current_type = select_one("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE '#{column_name}'")["Type"]
+ execute "ALTER TABLE #{quote_table_name(table_name)} CHANGE #{quote_column_name(column_name)} #{quote_column_name(new_column_name)} #{current_type}"
end
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index 6013d6e156..b314340f0c 100755
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -318,7 +318,7 @@ class Fixtures < YAML::Omap
end
def delete_existing_fixtures
- @connection.delete "DELETE FROM #{@table_name}", 'Fixture Delete'
+ @connection.delete "DELETE FROM #{@connection.quote_table_name(table_name)}", 'Fixture Delete'
end
def insert_fixtures