diff --git a/CHANGELOG.md b/CHANGELOG.md index 3889fec..d42b05d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## 0.6.2 (unreleased) +- Added `--disable-integrity-v2` option - Fixed error when excluded table not found in source ## 0.6.1 (2020-06-07) diff --git a/lib/pgsync/client.rb b/lib/pgsync/client.rb index 2c469f0..7b7a10e 100644 --- a/lib/pgsync/client.rb +++ b/lib/pgsync/client.rb @@ -70,6 +70,7 @@ def slop_options o.boolean "--defer-constraints", "defer constraints", default: false o.boolean "--disable-user-triggers", "disable non-system triggers", default: false o.boolean "--disable-integrity", "disable foreign key triggers", default: false + o.boolean "--disable-integrity-v2", "disable foreign key triggers", default: false o.boolean "-v", "--version", "print the version" o.boolean "-h", "--help", "prints help" o diff --git a/lib/pgsync/task.rb b/lib/pgsync/task.rb index 652c638..fc93fd8 100644 --- a/lib/pgsync/task.rb +++ b/lib/pgsync/task.rb @@ -275,7 +275,7 @@ def quoted_primary_key(table, primary_key, rule) end def maybe_disable_triggers - if opts[:disable_integrity] || opts[:disable_user_triggers] + if opts[:disable_integrity] || opts[:disable_integrity_v2] || opts[:disable_user_triggers] destination.transaction do triggers = destination.triggers(table) triggers.select! { |t| t["enabled"] == "t" } @@ -283,7 +283,10 @@ def maybe_disable_triggers integrity_triggers = internal_triggers.select { |t| t["integrity"] == "t" } restore_triggers = [] - if opts[:disable_integrity] + if opts[:disable_integrity_v2] + role = destination.execute("SHOW session_replication_role").first["session_replication_role"] + destination.execute("SET session_replication_role = replica") + elsif opts[:disable_integrity] integrity_triggers.each do |trigger| destination.execute("ALTER TABLE #{quoted_table} DISABLE TRIGGER #{quote_ident(trigger["name"])}") end @@ -300,6 +303,11 @@ def maybe_disable_triggers result = yield + if opts[:disable_integrity_v2] + raise Error, "Unknown role: #{role}" unless ["origin", "replica", "local"].include?(role) + destination.execute("SET session_replication_role = #{role}") + end + # restore triggers that were previously enabled restore_triggers.each do |trigger| destination.execute("ALTER TABLE #{quoted_table} ENABLE TRIGGER #{quote_ident(trigger["name"])}") diff --git a/test/sync_test.rb b/test/sync_test.rb index 816b843..f9d8891 100644 --- a/test/sync_test.rb +++ b/test/sync_test.rb @@ -118,4 +118,14 @@ def test_disable_integrity assert_equal [], conn2.exec("SELECT * FROM posts ORDER BY id").to_a assert_equal [{"post_id" => 1}], conn2.exec("SELECT post_id FROM comments ORDER BY post_id").to_a end + + def test_disable_integrity_v2 + insert(conn1, "posts", [{"id" => 1}]) + insert(conn1, "comments", [{"post_id" => 1}]) + assert_error "Sync failed for 1 table: comments", "comments", config: true + assert_works "comments --disable-integrity-v2", config: true + # integrity is lost! (as expected) + assert_equal [], conn2.exec("SELECT * FROM posts ORDER BY id").to_a + assert_equal [{"post_id" => 1}], conn2.exec("SELECT post_id FROM comments ORDER BY post_id").to_a + end end