Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 7932

Show
Ignore:
Timestamp:
10/16/07 05:06:33 (2 years ago)
Author:
bitsweat
Message:

Quote table names. Defaults to column quoting. Closes #4593.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/activerecord/CHANGELOG

    r7913 r7932  
    11*SVN* 
     2 
     3* Quote table names. Defaults to column quoting.  #4593 [Justin Lynn, gwcoffey, eadz, Dmitry V. Sabanin, Jeremy Kemper] 
    24 
    35* Alias association #build to #new so it behaves predictably.  #8787 [lifofifo] 
  • trunk/activerecord/lib/active_record/base.rb

    r7908 r7932  
    532532      #   Post.delete_all "person_id = 5 AND (category = 'Something' OR category = 'Else')" 
    533533      def delete_all(conditions = nil) 
    534         sql = "DELETE FROM #{table_name} " 
     534        sql = "DELETE FROM #{quoted_table_name} " 
    535535        add_conditions!(sql, conditions, scope(:find)) 
    536536        connection.delete(sql, "#{name} Delete all") 
     
    10341034        def find_one(id, options) 
    10351035          conditions = " AND (#{sanitize_sql(options[:conditions])})" if options[:conditions] 
    1036           options.update :conditions => "#{table_name}.#{connection.quote_column_name(primary_key)} = #{quote_value(id,columns_hash[primary_key])}#{conditions}" 
     1036          options.update :conditions => "#{quoted_table_name}.#{connection.quote_column_name(primary_key)} = #{quote_value(id,columns_hash[primary_key])}#{conditions}" 
    10371037 
    10381038          # Use find_every(options).first since the primary key condition 
     
    10491049          conditions = " AND (#{sanitize_sql(options[:conditions])})" if options[:conditions] 
    10501050          ids_list   = ids.map { |id| quote_value(id,columns_hash[primary_key]) }.join(',') 
    1051           options.update :conditions => "#{table_name}.#{connection.quote_column_name(primary_key)} IN (#{ids_list})#{conditions}" 
     1051          options.update :conditions => "#{quoted_table_name}.#{connection.quote_column_name(primary_key)} IN (#{ids_list})#{conditions}" 
    10521052 
    10531053          result = find_every(options) 
     
    11271127        def construct_finder_sql(options) 
    11281128          scope = scope(:find) 
    1129           sql  = "SELECT #{(scope && scope[:select]) || options[:select] || (options[:joins] && table_name + '.*') || '*'} " 
    1130           sql << "FROM #{(scope && scope[:from]) || options[:from] || table_name} " 
     1129          sql  = "SELECT #{(scope && scope[:select]) || options[:select] || (options[:joins] && quoted_table_name + '.*') || '*'} " 
     1130          sql << "FROM #{(scope && scope[:from]) || options[:from] || quoted_table_name} " 
    11311131 
    11321132          add_joins!(sql, options, scope) 
     
    12211221        def type_condition 
    12221222          quoted_inheritance_column = connection.quote_column_name(inheritance_column) 
    1223           type_condition = subclasses.inject("#{table_name}.#{quoted_inheritance_column} = '#{name.demodulize}' ") do |condition, subclass| 
    1224             condition << "OR #{table_name}.#{quoted_inheritance_column} = '#{subclass.name.demodulize}' " 
     1223          type_condition = subclasses.inject("#{quoted_table_name}.#{quoted_inheritance_column} = '#{name.demodulize}' ") do |condition, subclass| 
     1224            condition << "OR #{quoted_table_name}.#{quoted_inheritance_column} = '#{subclass.name.demodulize}' " 
    12251225          end 
    12261226 
     
    15731573        def sanitize_sql_hash_for_conditions(attrs) 
    15741574          conditions = attrs.map do |attr, value| 
    1575             "#{table_name}.#{connection.quote_column_name(attr)} #{attribute_condition(value)}" 
     1575            "#{quoted_table_name}.#{connection.quote_column_name(attr)} #{attribute_condition(value)}" 
    15761576          end.join(' AND ') 
    15771577 
     
    17431743        unless new_record? 
    17441744          connection.delete <<-end_sql, "#{self.class.name} Destroy" 
    1745             DELETE FROM #{self.class.table_name} 
     1745            DELETE FROM #{self.class.quoted_table_name} 
    17461746            WHERE #{connection.quote_column_name(self.class.primary_key)} = #{quoted_id} 
    17471747          end_sql 
     
    19871987        return 0 if quoted_attributes.empty? 
    19881988        connection.update( 
    1989           "UPDATE #{self.class.table_name} " + 
     1989          "UPDATE #{self.class.quoted_table_name} " + 
    19901990          "SET #{quoted_comma_pair_list(connection, quoted_attributes)} " + 
    19911991          "WHERE #{connection.quote_column_name(self.class.primary_key)} = #{quote_value(id)}", 
     
    20062006          connection.empty_insert_statement(self.class.table_name) 
    20072007        else 
    2008           "INSERT INTO #{self.class.table_name} " + 
     2008          "INSERT INTO #{self.class.quoted_table_name} " + 
    20092009          "(#{quoted_column_names.join(', ')}) " + 
    20102010          "VALUES(#{quoted_attributes.values.join(', ')})" 
     
    21812181      end 
    21822182 
     2183      def self.quoted_table_name 
     2184        self.connection.quote_table_name(self.table_name) 
     2185      end 
     2186 
    21832187      def quote_columns(quoter, hash) 
    21842188        hash.inject({}) do |quoted, (name, value)| 
  • trunk/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb

    r7666 r7932  
    6464      end 
    6565 
     66      # QUOTING ================================================== 
     67 
     68      # Override to return the quoted table name if the database needs it 
     69      def quote_table_name(name) 
     70        name 
     71      end 
    6672 
    6773      # CONNECTION MANAGEMENT ==================================== 
  • trunk/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb

    r7753 r7932  
    137137      # something beyond a simple insert (eg. Oracle). 
    138138      def insert_fixture(fixture, table_name) 
    139         execute "INSERT INTO #{table_name} (#{fixture.key_list}) VALUES (#{fixture.value_list})", 'Fixture Insert' 
     139        execute "INSERT INTO #{quote_table_name(table_name)} (#{fixture.key_list}) VALUES (#{fixture.value_list})", 'Fixture Insert' 
    140140      end 
    141141 
    142142      def empty_insert_statement(table_name) 
    143         "INSERT INTO #{table_name} VALUES(DEFAULT)" 
     143        "INSERT INTO #{quote_table_name(table_name)} VALUES(DEFAULT)" 
    144144      end 
    145145 
  • trunk/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb

    r7329 r7932  
    4040      end 
    4141 
    42       # Returns a quoted form of the column name.  This is highly adapter 
    43       # specific. 
    44       def quote_column_name(name) 
    45         name 
     42      # Quotes the column name. Defaults to no quoting. 
     43      def quote_column_name(column_name) 
     44        column_name 
     45      end 
     46 
     47      # Quotes the table name. Defaults to column name quoting. 
     48      def quote_table_name(table_name) 
     49        quote_column_name(table_name) 
    4650      end 
    4751 
  • trunk/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb

    r7931 r7932  
    8888      # 
    8989      # See also TableDefinition#column for details on how to create columns. 
    90       def create_table(name, options = {}) 
     90      def create_table(table_name, options = {}) 
    9191        table_definition = TableDefinition.new(self) 
    9292        table_definition.primary_key(options[:primary_key] || "id") unless options[:id] == false 
     
    9595 
    9696        if options[:force] 
    97           drop_table(name, options) rescue nil 
     97          drop_table(table_name, options) rescue nil 
    9898        end 
    9999 
    100100        create_sql = "CREATE#{' TEMPORARY' if options[:temporary]} TABLE " 
    101         create_sql << "#{name} (" 
     101        create_sql << "#{quote_table_name(table_name)} (" 
    102102        create_sql << table_definition.to_sql 
    103103        create_sql << ") #{options[:options]}" 
    104104        execute create_sql 
    105105      end 
    106        
     106 
    107107      # Renames a table. 
    108108      # ===== Example 
    109109      #  rename_table('octopuses', 'octopi') 
    110       def rename_table(name, new_name) 
     110      def rename_table(table_name, new_name) 
    111111        raise NotImplementedError, "rename_table is not implemented" 
    112112      end 
    113113 
    114114      # Drops a table from the database. 
    115       def drop_table(name, options = {}) 
    116         execute "DROP TABLE #{name}" 
     115      def drop_table(table_name, options = {}) 
     116        execute "DROP TABLE #{quote_table_name(table_name)}" 
    117117      end 
    118118 
     
    120120      # See TableDefinition#column for details of the options you can use. 
    121121      def add_column(table_name, column_name, type, options = {}) 
    122         add_column_sql = "ALTER TABLE #{table_name} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}" 
     122        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])}" 
    123123        add_column_options!(add_column_sql, options) 
    124124        execute(add_column_sql) 
     
    129129      #  remove_column(:suppliers, :qualification) 
    130130      def remove_column(table_name, column_name) 
    131         execute "ALTER TABLE #{table_name} DROP #{quote_column_name(column_name)}" 
     131        execute "ALTER TABLE #{quote_table_name(table_name)} DROP #{quote_column_name(column_name)}" 
    132132      end 
    133133 
     
    195195        end 
    196196        quoted_column_names = column_names.map { |e| quote_column_name(e) }.join(", ") 
    197         execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{table_name} (#{quoted_column_names})" 
     197        execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{quoted_column_names})" 
    198198      end 
    199199 
     
    235235      def initialize_schema_information 
    236236        begin 
    237           execute "CREATE TABLE #{ActiveRecord::Migrator.schema_info_table_name} (version #{type_to_sql(:integer)})" 
    238           execute "INSERT INTO #{ActiveRecord::Migrator.schema_info_table_name} (version) VALUES(0)" 
     237          execute "CREATE TABLE #{quote_table_name(ActiveRecord::Migrator.schema_info_table_name)} (version #{type_to_sql(:integer)})" 
     238          execute "INSERT INTO #{quote_table_name(ActiveRecord::Migrator.schema_info_table_name)} (version) VALUES(0)" 
    239239        rescue ActiveRecord::StatementInvalid 
    240240          # Schema has been initialized 
     
    245245        begin 
    246246          if (current_schema = ActiveRecord::Migrator.current_version) > 0 
    247             return "INSERT INTO #{ActiveRecord::Migrator.schema_info_table_name} (version) VALUES (#{current_schema})"  
     247            return "INSERT INTO #{quote_table_name(ActiveRecord::Migrator.schema_info_table_name)} (version) VALUES (#{current_schema})"  
    248248          end 
    249249        rescue ActiveRecord::StatementInvalid  
  • trunk/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb

    r7790 r7932  
    209209      end 
    210210 
     211      def quote_table_name(name) #:nodoc: 
     212        quote_column_name(name) 
     213      end 
     214 
    211215      def quote_string(string) #:nodoc: 
    212216        @connection.quote(string) 
     
    323327        select_all(sql).inject("") do |structure, table| 
    324328          table.delete('Table_type') 
    325           structure += select_one("SHOW CREATE TABLE #{table.to_a.first.last}")["Create Table"] + ";\n\n" 
     329          structure += select_one("SHOW CREATE TABLE #{quote_table_name(table.to_a.first.last)}")["Create Table"] + ";\n\n" 
    326330        end 
    327331      end 
     
    371375      end 
    372376 
     377      def drop_table(table_name, options = {}) 
     378        super(table_name, options) 
     379      end 
     380 
    373381      def indexes(table_name, name = nil)#:nodoc: 
    374382        indexes = [] 
    375383        current_index = nil 
    376         execute("SHOW KEYS FROM #{table_name}", name).each do |row| 
     384        execute("SHOW KEYS FROM #{quote_table_name(table_name)}", name).each do |row| 
    377385          if current_index != row[2] 
    378386            next if row[2] == "PRIMARY" # skip the primary key 
     
    387395 
    388396      def columns(table_name, name = nil)#:nodoc: 
    389         sql = "SHOW FIELDS FROM #{table_name}" 
     397        sql = "SHOW FIELDS FROM #{quote_table_name(table_name)}" 
    390398        columns = [] 
    391399        execute(sql, name).each { |field| columns << MysqlColumn.new(field[0], field[4], field[1], field[2] == "YES") } 
     
    393401      end 
    394402 
    395       def create_table(name, options = {}) #:nodoc: 
    396         super(name, {:options => "ENGINE=InnoDB"}.merge(options)) 
    397       end 
    398  
    399       def rename_table(name, new_name) 
    400         execute "RENAME TABLE #{name} TO #{new_name}" 
     403      def create_table(table_name, options = {}) #:nodoc: 
     404        super(table_name, options.reverse_merge(:options => "ENGINE=InnoDB")) 
     405      end 
     406 
     407      def rename_table(table_name, new_name) 
     408        execute "RENAME TABLE #{quote_table_name(table_name)} TO #{quote_table_name(new_name)}" 
    401409      end 
    402410 
    403411      def change_column_default(table_name, column_name, default) #:nodoc: 
    404         current_type = select_one("SHOW COLUMNS FROM #{table_name} LIKE '#{column_name}'")["Type"] 
    405  
    406         execute("ALTER TABLE #{table_name} CHANGE #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{current_type} DEFAULT #{quote(default)}") 
     412        current_type = select_one("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE '#{column_name}'")["Type"] 
     413 
     414        execute("ALTER TABLE #{quote_table_name(table_name)} CHANGE #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{current_type} DEFAULT #{quote(default)}") 
    407415      end 
    408416 
     
    416424        end 
    417425 
    418         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])}" 
     426        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])}" 
    419427        add_column_options!(change_column_sql, options) 
    420428        execute(change_column_sql) 
     
    422430 
    423431      def rename_column(table_name, column_name, new_column_name) #:nodoc: 
    424         current_type = select_one("SHOW COLUMNS FROM #{table_name} LIKE '#{column_name}'")["Type"] 
    425         execute "ALTER TABLE #{table_name} CHANGE #{quote_column_name(column_name)} #{quote_column_name(new_column_name)} #{current_type}" 
     432        current_type = select_one("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE '#{column_name}'")["Type"] 
     433        execute "ALTER TABLE #{quote_table_name(table_name)} CHANGE #{quote_column_name(column_name)} #{quote_column_name(new_column_name)} #{current_type}" 
    426434      end 
    427435 
  • trunk/activerecord/lib/active_record/fixtures.rb

    r7667 r7932  
    319319 
    320320  def delete_existing_fixtures 
    321     @connection.delete "DELETE FROM #{@table_name}", 'Fixture Delete' 
     321    @connection.delete "DELETE FROM #{@connection.quote_table_name(table_name)}", 'Fixture Delete' 
    322322  end 
    323323 
  • trunk/activerecord/test/active_schema_test_mysql.rb

    r6848 r7932  
    1414 
    1515  def test_drop_table 
    16     assert_equal "DROP TABLE people", drop_table(:people) 
     16    assert_equal "DROP TABLE `people`", drop_table(:people) 
    1717  end 
    1818 
     
    2626 
    2727  def test_add_column 
    28     assert_equal "ALTER TABLE people ADD `last_name` varchar(255)", add_column(:people, :last_name, :string) 
     28    assert_equal "ALTER TABLE `people` ADD `last_name` varchar(255)", add_column(:people, :last_name, :string) 
    2929  end 
    3030 
    3131  def test_add_column_with_limit 
    32     assert_equal "ALTER TABLE people ADD `key` varchar(32)", add_column(:people, :key, :string, :limit => 32) 
     32    assert_equal "ALTER TABLE `people` ADD `key` varchar(32)", add_column(:people, :key, :string, :limit => 32) 
    3333  end 
    3434