Skip to content

Commit eca26d5

Browse files
committed
Replice terminate_backend with WITH (FORCE)
1 parent 9d75fe1 commit eca26d5

File tree

2 files changed

+20
-11
lines changed

2 files changed

+20
-11
lines changed

pkg/postgres/database.go

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const (
1212
CREATE_EXTENSION = `CREATE EXTENSION IF NOT EXISTS "%s"`
1313
ALTER_DB_OWNER = `ALTER DATABASE "%s" OWNER TO "%s"`
1414
REASSIGN_DB_OWNER = `REASSIGN OWNED BY "%s" TO "%s"`
15-
DROP_DATABASE = `DROP DATABASE "%s"`
15+
DROP_DATABASE = `DROP DATABASE "%s" WITH (FORCE)`
1616
GRANT_USAGE_SCHEMA = `GRANT USAGE ON SCHEMA "%s" TO "%s"`
1717
GRANT_CREATE_TABLE = `GRANT CREATE ON SCHEMA "%s" TO "%s"`
1818
GRANT_ALL_TABLES = `GRANT %s ON ALL TABLES IN SCHEMA "%s" TO "%s"`
@@ -22,9 +22,9 @@ const (
2222
GRANT_ALL_SEQUENCES = `GRANT %s ON ALL SEQUENCES IN SCHEMA "%s" TO "%s"`
2323
DEFAULT_PRIVS_SEQUENCES = `ALTER DEFAULT PRIVILEGES IN SCHEMA "%s" GRANT %s ON SEQUENCES TO "%s"`
2424
REVOKE_CONNECT = `REVOKE CONNECT ON DATABASE "%s" FROM public`
25-
TERMINATE_BACKEND = `SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '%s' AND pid <> pg_backend_pid()`
2625
GET_DB_OWNER = `SELECT pg_catalog.pg_get_userbyid(d.datdba) FROM pg_catalog.pg_database d WHERE d.datname = '%s'`
2726
GRANT_CREATE_SCHEMA = `GRANT CREATE ON DATABASE "%s" TO "%s"`
27+
GRANT_CONNECT = `GRANT CONNECT ON DATABASE "%s" TO "%s"`
2828
)
2929

3030
func (c *pg) CreateDB(dbname, role string) error {
@@ -42,9 +42,20 @@ func (c *pg) CreateDB(dbname, role string) error {
4242
return err
4343
}
4444

45-
err = c.execute(fmt.Sprintf(GRANT_CREATE_SCHEMA, dbname, role))
46-
if err != nil {
47-
return err
45+
// Grant CREATE on database to owner and operator user
46+
usersToGrant := []string{c.user, role}
47+
for _, u := range usersToGrant {
48+
err = c.execute(fmt.Sprintf(GRANT_CREATE_SCHEMA, dbname, u))
49+
if err != nil {
50+
return fmt.Errorf("failed to grant create schema on %s to %s: %w", dbname, u, err)
51+
}
52+
}
53+
// Grant CONNECT on database to owner and operator user
54+
for _, u := range usersToGrant {
55+
err = c.execute(fmt.Sprintf(GRANT_CONNECT, dbname, u))
56+
if err != nil {
57+
return fmt.Errorf("failed to grant connect on %s to %s: %w", dbname, u, err)
58+
}
4859
}
4960
return nil
5061
}
@@ -99,11 +110,6 @@ func (c *pg) DropDatabase(database string, logger logr.Logger) error {
99110
return err
100111
}
101112

102-
err = c.execute(fmt.Sprintf(TERMINATE_BACKEND, database))
103-
// Error code 3D000 is returned if database doesn't exist
104-
if err != nil && !isPgError(err, "3D000") {
105-
return err
106-
}
107113
err = c.execute(fmt.Sprintf(DROP_DATABASE, database))
108114
// Error code 3D000 is returned if database doesn't exist
109115
if err != nil && !isPgError(err, "3D000") {

pkg/postgres/database_grants_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,14 @@ func TestCreateDB_GrantsCreateOnDatabase(t *testing.T) {
1414
}
1515
defer db.Close()
1616

17-
p := &pg{db: db}
17+
p := &pg{db: db, user: "operator"}
1818

1919
mock.ExpectExec(regexp.QuoteMeta(`CREATE DATABASE "mydb"`)).WillReturnResult(sqlmock.NewResult(0, 1))
2020
mock.ExpectExec(regexp.QuoteMeta(`ALTER DATABASE "mydb" OWNER TO "owner"`)).WillReturnResult(sqlmock.NewResult(0, 1))
21+
mock.ExpectExec(regexp.QuoteMeta(`GRANT CREATE ON DATABASE "mydb" TO "operator"`)).WillReturnResult(sqlmock.NewResult(0, 1))
2122
mock.ExpectExec(regexp.QuoteMeta(`GRANT CREATE ON DATABASE "mydb" TO "owner"`)).WillReturnResult(sqlmock.NewResult(0, 1))
23+
mock.ExpectExec(regexp.QuoteMeta(`GRANT CONNECT ON DATABASE "mydb" TO "operator"`)).WillReturnResult(sqlmock.NewResult(0, 1))
24+
mock.ExpectExec(regexp.QuoteMeta(`GRANT CONNECT ON DATABASE "mydb" TO "owner"`)).WillReturnResult(sqlmock.NewResult(0, 1))
2225

2326
if err := p.CreateDB("mydb", "owner"); err != nil {
2427
t.Fatalf("CreateDB: %v", err)

0 commit comments

Comments
 (0)