From 38703ac8972c7e8f3f3f1ac95aa506cc4ae30ef0 Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Tue, 13 Dec 2011 23:43:42 +0000 Subject: [PATCH] Revert naive O(1) table_exists? implementation. It was a bad idea to rescue exceptions here. This can interfere with transaction rollbacks which seems to be the cause of current CI failure. Instead, each adapter should implement its own DB-specific O(1) implementation, and we fall back on the generic, slower, implementation otherwise. --- .../abstract/schema_statements.rb | 7 +------ .../connection_adapters/abstract_mysql_adapter.rb | 13 ++++++++----- .../connection_adapters/sqlite_adapter.rb | 7 ++++++- activerecord/test/cases/adapter_test.rb | 1 + 4 files changed, 16 insertions(+), 12 deletions(-) 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 a905c135f8..ccbeba061d 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -16,17 +16,12 @@ module ActiveRecord table_name[0...table_alias_length].gsub(/\./, '_') end - # def tables(name = nil) end - # Checks to see if the table +table_name+ exists on the database. # # === Example # table_exists?(:developers) def table_exists?(table_name) - select_value("SELECT 1 FROM #{quote_table_name(table_name)} where 1=0", 'SCHEMA') - true - rescue - false + tables.include?(table_name.to_s) end # Returns an array of indexes for the given table. diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb index 4d2c80356d..560773ca86 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb @@ -152,7 +152,7 @@ module ActiveRecord true end - # Technically MySQL allows to create indexes with the sort order syntax + # Technically MySQL allows to create indexes with the sort order syntax # but at the moment (5.5) it doesn't yet implement them def supports_index_sort_order? true @@ -363,8 +363,10 @@ module ActiveRecord show_variable 'collation_database' end - def tables(name = nil, database = nil) #:nodoc: - sql = ["SHOW TABLES", database].compact.join(' IN ') + def tables(name = nil, database = nil, like = nil) #:nodoc: + sql = "SHOW TABLES " + sql << "IN #{database} " if database + sql << "LIKE #{quote(like)}" if like execute_and_free(sql, 'SCHEMA') do |result| result.collect { |field| field.first } @@ -372,7 +374,8 @@ module ActiveRecord end def table_exists?(name) - return true if super + return false unless name + return true if tables(nil, nil, name).any? name = name.to_s schema, table = name.split('.', 2) @@ -382,7 +385,7 @@ module ActiveRecord schema = nil end - tables(nil, schema).include? table + tables(nil, schema, table).any? end # Returns an array of indexes for the given table. diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb index b8e91a2aea..55818b3fbf 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb @@ -329,18 +329,23 @@ module ActiveRecord # SCHEMA STATEMENTS ======================================== - def tables(name = 'SCHEMA') #:nodoc: + def tables(name = 'SCHEMA', table_name = nil) #:nodoc: sql = <<-SQL SELECT name FROM sqlite_master WHERE type = 'table' AND NOT name = 'sqlite_sequence' SQL + sql << " AND name = #{quote_table_name(table_name)}" if table_name exec_query(sql, name).map do |row| row['name'] end end + def table_exists?(name) + name && tables('SCHEMA', name).any? + end + # Returns an array of +SQLiteColumn+ objects for the table specified by +table_name+. def columns(table_name, name = nil) #:nodoc: table_structure(table_name).map do |field| diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb index 5d5ff53004..56c359650e 100644 --- a/activerecord/test/cases/adapter_test.rb +++ b/activerecord/test/cases/adapter_test.rb @@ -17,6 +17,7 @@ module ActiveRecord def test_table_exists? assert @connection.table_exists?("accounts") assert !@connection.table_exists?("nonexistingtable") + assert !@connection.table_exists?(nil) end def test_indexes