Skip to content

Commit

Permalink
Merge pull request #24 from ww-daniel-mora/feat/sql-rollback
Browse files Browse the repository at this point in the history
feat(sql): enable rollback
  • Loading branch information
berenddeboer authored Jun 14, 2024
2 parents d8dd27c + 7fb5cd4 commit b57c7a5
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 3 deletions.
28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,30 @@ grant select on t to myrole;
})
```

Rollback sql on stack deletion:

```ts
const sql = new Sql(this, "Sql", {
provider: provider,
database: database,
statement: `
create table if not exists t (i int);
grant select on t to myrole;
`,
rollback: `
DO $$BEGIN
IF EXISTS (select from pg_database WHERE datname = 't') THEN
IF EXISTS (select from pg_catalog.pg_roles WHERE rolname = 'myrole') THEN
revoke select t from myrole;
END IF;
drop table t;
END IF;
END$$;
`
})
```


Note that there is no synchronisation between various `Sql`
constructs, in particular the order in your code does not determine
the order in which your SQL is executed. This happens in parallel,
Expand All @@ -219,8 +243,8 @@ There are a lot of concerns when using `Sql`:

- When you update your Sql, your previous Sql is not "rolled back",
the new Sql is simply executed again.
- The same when you delete your `Sql` construct: nothing is rolled
back in the database.
- When you delete your `Sql` construct the rollback is executed if specified
- When permission are granted via `Sql` they must be removed via rollback to succesfully remove the role
- Currently the `Sql` constructs has less than 5 minutes to execute
its work.
- It is unknown how large your SQL can be.
Expand Down
4 changes: 3 additions & 1 deletion src/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ const jumpTable: JumpTable = {
Update: (_: string, __: string, props?: any) => {
return props.Statement
},
Delete: (_: string) => {},
Delete: (_: string, __: string, props?: any) => {
return props.Rollback
},
},
schema: {
Create: async (resourceId: string) => {
Expand Down
6 changes: 6 additions & 0 deletions src/sql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ export interface SqlProps {
* SQL.
*/
readonly statement?: string

/**
* Optional statment to be executed when the resource is deleted
*/
readonly rollback?: string
}

export class Sql extends CustomResource {
Expand All @@ -32,6 +37,7 @@ export class Sql extends CustomResource {
SecretArn: props.provider.secret.secretArn,
DatabaseName: props.database ? props.database.databaseName : undefined,
Statement: props.statement,
Rollback: props.rollback,
},
})
this.node.addDependency(props.provider)
Expand Down
1 change: 1 addition & 0 deletions test/serverlessv1-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export class TestStack extends Stack {
provider: provider,
database: database,
statement: "create table t (i int)",
rollback: "drop table t",
})
}
}
10 changes: 10 additions & 0 deletions test/serverlessv2-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,16 @@ export class TestStack extends Stack {
statement: `
create table if not exists t (i int);
grant select on t to myrole;
`,
rollback: `
DO $$BEGIN
IF EXISTS (select from pg_database WHERE datname = 't') THEN
IF EXISTS (select from pg_catalog.pg_roles WHERE rolname = 'myrole') THEN
revoke select database t from myrole;
END IF;
drop table t;
END IF;
END$$;,
`,
})
}
Expand Down

0 comments on commit b57c7a5

Please sign in to comment.