always return Postgres table names with schema to avoid awfulness

- without the schema, the migrations table gets truncated since the default AR method returns ‘public.schema_migrations’
- also a possibility is truncation of tables other than desired once since without the schema, Postgres has no way of knowing which table to truncate if two schemas have the same table
This commit is contained in:
Billy Watson 2014-07-22 12:31:03 -04:00
parent f5edecafe9
commit 77bca129d6
2 changed files with 25 additions and 0 deletions

View file

@ -24,6 +24,7 @@ module DatabaseCleaner
def database_cleaner_view_cache def database_cleaner_view_cache
@views ||= select_values("select table_name from information_schema.views where table_schema = '#{current_database}'") rescue [] @views ||= select_values("select table_name from information_schema.views where table_schema = '#{current_database}'") rescue []
end end
def database_cleaner_table_cache def database_cleaner_table_cache
# the adapters don't do caching (#130) but we make the assumption that the list stays the same in tests # the adapters don't do caching (#130) but we make the assumption that the list stays the same in tests
@database_cleaner_tables ||= tables @database_cleaner_tables ||= tables
@ -155,6 +156,15 @@ module DatabaseCleaner
truncate_tables(tables.select(&filter)) truncate_tables(tables.select(&filter))
end end
def database_cleaner_table_cache
# AR returns a list of tables without schema but then returns a
# migrations table with the schema. There are other problems, too,
# with using the base list. If a table exists in multiple schemas
# within the search path, truncation without the schema name could
# result in confusing, if not unexpected results.
@database_cleaner_tables ||= tables_with_schema
end
private private
# Returns a boolean indicating if the given table has an auto-inc number higher than 0. # Returns a boolean indicating if the given table has an auto-inc number higher than 0.
@ -169,6 +179,15 @@ module DatabaseCleaner
def has_rows?(table) def has_rows?(table)
select_value("SELECT true FROM #{table} LIMIT 1;") select_value("SELECT true FROM #{table} LIMIT 1;")
end end
def tables_with_schema
rows = select_rows <<-_SQL
SELECT schemaname || '.' || tablename
FROM pg_tables
WHERE tablename !~ '_prt_' AND schemaname = ANY (current_schemas(false))
_SQL
rows.collect { |result| result.first }
end
end end
end end
end end

View file

@ -35,6 +35,12 @@ module ActiveRecord
end end
end end
describe '#database_cleaner_table_cache' do
it 'should default to the list of tables with their schema' do
connection.database_cleaner_table_cache.first.should match(/^public\./)
end
end
it_behaves_like "an adapter with pre-count truncation" do it_behaves_like "an adapter with pre-count truncation" do
let(:connection) { active_record_pg_connection } let(:connection) { active_record_pg_connection }
end end