From be1dd45200b1f21aec5b151d78ef402df9fa28e4 Mon Sep 17 00:00:00 2001 From: Rusty Geldmacher Date: Fri, 12 May 2017 11:40:31 -0400 Subject: Respect `ignore_tables` in Postgres structure dump When using `sql` as the schema format, or even just doing `rake db:structure:dump`, it would be good to respect the list of ignored tables that has been configured. --- activerecord/lib/active_record/tasks/postgresql_database_tasks.rb | 6 ++++++ activerecord/test/cases/tasks/postgresql_rake_test.rb | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb index f1af90c1e8..7f1a768d8b 100644 --- a/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb +++ b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb @@ -66,6 +66,12 @@ module ActiveRecord "--schema=#{part.strip}" end end + + ignore_tables = ActiveRecord::SchemaDumper.ignore_tables + if ignore_tables.any? + args += ignore_tables.flat_map { |table| ["-T", table] } + end + args << configuration["database"] run_cmd("pg_dump", args, "dumping") remove_sql_header_comments(filename) diff --git a/activerecord/test/cases/tasks/postgresql_rake_test.rb b/activerecord/test/cases/tasks/postgresql_rake_test.rb index 512388af6b..a2e968aedf 100644 --- a/activerecord/test/cases/tasks/postgresql_rake_test.rb +++ b/activerecord/test/cases/tasks/postgresql_rake_test.rb @@ -259,6 +259,14 @@ if current_adapter?(:PostgreSQLAdapter) end end + def test_structure_dump_with_ignore_tables + ActiveRecord::SchemaDumper.expects(:ignore_tables).returns(["foo", "bar"]) + + Kernel.expects(:system).with("pg_dump", "-s", "-x", "-O", "-f", @filename, "-T", "foo", "-T", "bar", "my-app-db").returns(true) + + ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename) + end + def test_structure_dump_with_schema_search_path @configuration["schema_search_path"] = "foo,bar" -- cgit v1.2.3 From 486562fa955f2cbd574e7f4099fdf69a49a8ce20 Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Sat, 13 May 2017 21:35:22 -0500 Subject: Respect 'ignore_tables' in MySQL structure dump --- .../lib/active_record/tasks/mysql_database_tasks.rb | 6 ++++++ activerecord/test/cases/tasks/mysql_rake_test.rb | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/activerecord/lib/active_record/tasks/mysql_database_tasks.rb b/activerecord/lib/active_record/tasks/mysql_database_tasks.rb index c05f0a8fbb..541165b3d1 100644 --- a/activerecord/lib/active_record/tasks/mysql_database_tasks.rb +++ b/activerecord/lib/active_record/tasks/mysql_database_tasks.rb @@ -60,6 +60,12 @@ module ActiveRecord args.concat(["--routines"]) args.concat(["--skip-comments"]) args.concat(Array(extra_flags)) if extra_flags + + ignore_tables = ActiveRecord::SchemaDumper.ignore_tables + if ignore_tables.any? + args += ignore_tables.map { |table| "--ignore-table=#{configuration['database']}.#{table}" } + end + args.concat(["#{configuration['database']}"]) run_cmd("mysqldump", args, "dumping") diff --git a/activerecord/test/cases/tasks/mysql_rake_test.rb b/activerecord/test/cases/tasks/mysql_rake_test.rb index b85d303a91..33da3d11fc 100644 --- a/activerecord/test/cases/tasks/mysql_rake_test.rb +++ b/activerecord/test/cases/tasks/mysql_rake_test.rb @@ -294,6 +294,13 @@ if current_adapter?(:Mysql2Adapter) ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, filename) end + def test_structure_dump + filename = "awesome-file.sql" + Kernel.expects(:system).with("mysqldump", "--result-file", filename, "--no-data", "--routines", "--skip-comments", "test-db").returns(true) + + ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, filename) + end + def test_structure_dump_with_extra_flags filename = "awesome-file.sql" expected_command = ["mysqldump", "--result-file", filename, "--no-data", "--routines", "--skip-comments", "--noop", "test-db"] @@ -305,6 +312,15 @@ if current_adapter?(:Mysql2Adapter) end end + def test_structure_dump_with_ignore_tables + filename = "awesome-file.sql" + ActiveRecord::SchemaDumper.expects(:ignore_tables).returns(["foo", "bar"]) + + Kernel.expects(:system).with("mysqldump", "--result-file", filename, "--no-data", "--routines", "--skip-comments", "--ignore-table=test-db.foo", "--ignore-table=test-db.bar", "test-db").returns(true) + + ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, filename) + end + def test_warn_when_external_structure_dump_command_execution_fails filename = "awesome-file.sql" Kernel.expects(:system) -- cgit v1.2.3 From 4b49ab66425283f4b79907873b72236c7ebec0be Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Sat, 13 May 2017 23:01:13 -0500 Subject: Respect 'ignore_tables' in SQLite structure dump --- .../lib/active_record/tasks/sqlite_database_tasks.rb | 11 ++++++++++- activerecord/test/cases/tasks/sqlite_rake_test.rb | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb b/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb index 1f756c2979..5542e5585c 100644 --- a/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb +++ b/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb @@ -38,7 +38,16 @@ module ActiveRecord def structure_dump(filename, extra_flags) dbfile = configuration["database"] flags = extra_flags.join(" ") if extra_flags - `sqlite3 #{flags} #{dbfile} .schema > #{filename}` + + ignore_tables = ActiveRecord::SchemaDumper.ignore_tables + if ignore_tables.any? + tables = `sqlite3 #{dbfile} .tables`.split - ignore_tables + condition = tables.map { |table| "tbl_name = '#{table}'" }.join(" OR ") + statement = "SELECT sql FROM sqlite_master WHERE #{condition} ORDER BY tbl_name, type DESC, name" + `sqlite3 #{flags} #{dbfile} "#{statement}" > #{filename}` + else + `sqlite3 #{flags} #{dbfile} .schema > #{filename}` + end end def structure_load(filename, extra_flags) diff --git a/activerecord/test/cases/tasks/sqlite_rake_test.rb b/activerecord/test/cases/tasks/sqlite_rake_test.rb index 0d917f3f6c..ccb3834fee 100644 --- a/activerecord/test/cases/tasks/sqlite_rake_test.rb +++ b/activerecord/test/cases/tasks/sqlite_rake_test.rb @@ -180,6 +180,9 @@ if current_adapter?(:SQLite3Adapter) "adapter" => "sqlite3", "database" => @database } + + `sqlite3 #{@database} 'CREATE TABLE bar(id INTEGER)'` + `sqlite3 #{@database} 'CREATE TABLE foo(id INTEGER)'` end def test_structure_dump @@ -189,6 +192,23 @@ if current_adapter?(:SQLite3Adapter) ActiveRecord::Tasks::DatabaseTasks.structure_dump @configuration, filename, "/rails/root" assert File.exist?(dbfile) assert File.exist?(filename) + assert_match(/CREATE TABLE foo/, File.read(filename)) + assert_match(/CREATE TABLE bar/, File.read(filename)) + ensure + FileUtils.rm_f(filename) + FileUtils.rm_f(dbfile) + end + + def test_structure_dump_with_ignore_tables + dbfile = @database + filename = "awesome-file.sql" + ActiveRecord::SchemaDumper.expects(:ignore_tables).returns(["foo"]) + + ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, filename, "/rails/root") + assert File.exist?(dbfile) + assert File.exist?(filename) + assert_match(/bar/, File.read(filename)) + assert_no_match(/foo/, File.read(filename)) ensure FileUtils.rm_f(filename) FileUtils.rm_f(dbfile) -- cgit v1.2.3 From 0b921f5d3ebaed95dcc0d8304f054a9ccf672141 Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Sat, 13 May 2017 23:02:08 -0500 Subject: Update SchemaDumper.ignore_tables docs --- activerecord/lib/active_record/schema_dumper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/schema_dumper.rb b/activerecord/lib/active_record/schema_dumper.rb index 94d63765c9..24b81aabc8 100644 --- a/activerecord/lib/active_record/schema_dumper.rb +++ b/activerecord/lib/active_record/schema_dumper.rb @@ -11,8 +11,8 @@ module ActiveRecord ## # :singleton-method: # A list of tables which should not be dumped to the schema. - # Acceptable values are strings as well as regexp. - # This setting is only used if ActiveRecord::Base.schema_format == :ruby + # Acceptable values are strings as well as regexp if ActiveRecord::Base.schema_format == :ruby. + # Only strings are accepted if ActiveRecord::Base.schema_format == :sql. cattr_accessor :ignore_tables @@ignore_tables = [] -- cgit v1.2.3 From f98c97d37996b648a27c80166f0fc60ac94f76e2 Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Sun, 14 May 2017 12:15:35 -0500 Subject: Improvements for SQLite rake task. * Use NOT IN in SQL query * Quote table names propertly * Use array form of command invocation --- .../active_record/tasks/sqlite_database_tasks.rb | 25 ++++++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb b/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb index 5542e5585c..7043d2f0c8 100644 --- a/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb +++ b/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb @@ -36,18 +36,18 @@ module ActiveRecord end def structure_dump(filename, extra_flags) - dbfile = configuration["database"] - flags = extra_flags.join(" ") if extra_flags + args = [] + args.concat(Array(extra_flags)) if extra_flags + args << configuration["database"] ignore_tables = ActiveRecord::SchemaDumper.ignore_tables if ignore_tables.any? - tables = `sqlite3 #{dbfile} .tables`.split - ignore_tables - condition = tables.map { |table| "tbl_name = '#{table}'" }.join(" OR ") - statement = "SELECT sql FROM sqlite_master WHERE #{condition} ORDER BY tbl_name, type DESC, name" - `sqlite3 #{flags} #{dbfile} "#{statement}" > #{filename}` + condition = ignore_tables.map { |table| connection.quote_table_name(table) }.join(", ") + args << "SELECT sql FROM sqlite_master WHERE tbl_name NOT IN (#{condition}) ORDER BY tbl_name, type DESC, name" else - `sqlite3 #{flags} #{dbfile} .schema > #{filename}` + args << ".schema" end + run_cmd("sqlite3", args, filename) end def structure_load(filename, extra_flags) @@ -65,6 +65,17 @@ module ActiveRecord def root @root end + + def run_cmd(cmd, args, out) + fail run_cmd_error(cmd, args) unless Kernel.system(cmd, *args, out: out) + end + + def run_cmd_error(cmd, args) + msg = "failed to execute:\n" + msg << "#{cmd} #{args.join(' ')}\n\n" + msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n" + msg + end end end end -- cgit v1.2.3 From 701663e18c856d182265867fb50854d58a8b79d0 Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Mon, 15 May 2017 18:24:33 -0500 Subject: Changelog entry [ci-skip] --- activerecord/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 2e059805a2..4e264f5f2a 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,7 @@ +* Respect 'SchemaDumper.ignore_tables' in rake tasks for databases structure dump + + *Rusty Geldmacher*, *Guillermo Iguaran* + * Add type caster to `RuntimeReflection#alias_name` Fixes #28959. -- cgit v1.2.3