DisableInPostgreSQL removes any objects created by EnableInPostgreSQL.
(ctx context.Context, exec postgres.Executor)
| 56 | |
| 57 | // DisableInPostgreSQL removes any objects created by EnableInPostgreSQL. |
| 58 | func DisableInPostgreSQL(ctx context.Context, exec postgres.Executor) error { |
| 59 | log := logging.FromContext(ctx) |
| 60 | |
| 61 | // First, remove PgBouncer objects from all databases and database templates. |
| 62 | // The PgBouncer user is removed later. |
| 63 | stdout, stderr, err := exec.ExecInAllDatabases(ctx, |
| 64 | strings.Join([]string{ |
| 65 | // Quiet NOTICE messages from IF EXISTS statements. |
| 66 | // - https://www.postgresql.org/docs/current/runtime-config-client.html |
| 67 | `SET client_min_messages = WARNING;`, |
| 68 | |
| 69 | // Do not wait for changes to be replicated. [Since PostgreSQL v9.1] |
| 70 | // - https://www.postgresql.org/docs/current/runtime-config-wal.html |
| 71 | `SET synchronous_commit = LOCAL;`, |
| 72 | |
| 73 | // Drop the following objects in a transaction. |
| 74 | `BEGIN;`, |
| 75 | |
| 76 | // Remove the "get_auth" function that returns user credentials to PgBouncer. |
| 77 | `DROP FUNCTION IF EXISTS :"namespace".get_auth(username TEXT);`, |
| 78 | |
| 79 | // Drop the PgBouncer schema and anything within it. |
| 80 | `DROP SCHEMA IF EXISTS :"namespace" CASCADE;`, |
| 81 | |
| 82 | // Ensure there's nothing else unexpectedly owned by the PgBouncer |
| 83 | // user in this database. Any privileges on shared objects are also |
| 84 | // removed. |
| 85 | strings.TrimSpace(` |
| 86 | SELECT pg_catalog.format('DROP OWNED BY %I CASCADE', :'username') |
| 87 | WHERE EXISTS (SELECT 1 FROM pg_catalog.pg_roles WHERE rolname = :'username') |
| 88 | \gexec`), |
| 89 | |
| 90 | // Commit (finish) the transaction. |
| 91 | `COMMIT;`, |
| 92 | }, "\n"), |
| 93 | map[string]string{ |
| 94 | "username": PostgresqlUser, |
| 95 | "namespace": postgresqlSchema, |
| 96 | |
| 97 | "ON_ERROR_STOP": "on", // Abort when any one statement fails. |
| 98 | "QUIET": "on", // Do not print successful statements to stdout. |
| 99 | }) |
| 100 | |
| 101 | log.V(1).Info("removed PgBouncer objects", "stdout", stdout, "stderr", stderr) |
| 102 | |
| 103 | if err == nil { |
| 104 | // Remove the PgBouncer user now that the objects and other privileges are gone. |
| 105 | stdout, stderr, err = exec.ExecInDatabasesFromQuery(ctx, |
| 106 | `SELECT pg_catalog.current_database()`, |
| 107 | `SET client_min_messages = WARNING; SET synchronous_commit = LOCAL; DROP ROLE IF EXISTS :"username";`, |
| 108 | map[string]string{ |
| 109 | "username": PostgresqlUser, |
| 110 | |
| 111 | "ON_ERROR_STOP": "on", // Abort when any one statement fails. |
| 112 | "QUIET": "on", // Do not print successful statements to stdout. |
| 113 | }) |
| 114 | |
| 115 | log.V(1).Info("removed PgBouncer user", "stdout", stdout, "stderr", stderr) |