From 77bca129d6031571b4da1edf63b9f5ae93fc6ee2 Mon Sep 17 00:00:00 2001 From: Billy Watson Date: Tue, 22 Jul 2014 12:31:03 -0400 Subject: [PATCH] always return Postgres table names with schema to avoid awfulness MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- .../active_record/truncation.rb | 19 +++++++++++++++++++ .../truncation/postgresql_spec.rb | 6 ++++++ 2 files changed, 25 insertions(+) diff --git a/lib/database_cleaner/active_record/truncation.rb b/lib/database_cleaner/active_record/truncation.rb index fb1a52c..78183e8 100755 --- a/lib/database_cleaner/active_record/truncation.rb +++ b/lib/database_cleaner/active_record/truncation.rb @@ -24,6 +24,7 @@ module DatabaseCleaner def database_cleaner_view_cache @views ||= select_values("select table_name from information_schema.views where table_schema = '#{current_database}'") rescue [] end + 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 @database_cleaner_tables ||= tables @@ -155,6 +156,15 @@ module DatabaseCleaner truncate_tables(tables.select(&filter)) 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 # 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) select_value("SELECT true FROM #{table} LIMIT 1;") 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 diff --git a/spec/database_cleaner/active_record/truncation/postgresql_spec.rb b/spec/database_cleaner/active_record/truncation/postgresql_spec.rb index 80a0d38..6a479d0 100644 --- a/spec/database_cleaner/active_record/truncation/postgresql_spec.rb +++ b/spec/database_cleaner/active_record/truncation/postgresql_spec.rb @@ -35,6 +35,12 @@ module ActiveRecord 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 let(:connection) { active_record_pg_connection } end