Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Role operations #100

Merged
merged 1 commit into from
Jul 19, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 83 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,28 +304,7 @@ This is required for some SQL operations that cannot be run within a transaction

-----------------------------------------------------

### Miscellaneous Operations

#### `pgm.sql( sql )`

> Run raw sql -- with some optional _[very basic](http://mir.aculo.us/2011/03/09/little-helpers-a-tweet-sized-javascript-templating-engine/)_ mustache templating

**Arguments:**
- `sql` _[string]_ - SQL query to run
- `args` _[object]_ - (optional) key/val of arguments to replace

-----------------------------------------------------

#### `pgm.func( sql )`

> Inserts raw string, which is not escaped

e.g. `pgm.func('CURRENT_TIMESTAMP')` to use in `default` option for column definition

**Arguments:**
- `sql` _[string]_ - string to not be escaped

-----------------------------------------------------
### Extension Operations

#### `pgm.createExtension( extension )`

Expand All @@ -348,8 +327,9 @@ e.g. `pgm.func('CURRENT_TIMESTAMP')` to use in `default` option for column defin

-----------------------------------------------------

#### `pgm.createType( type_name, values )`
### Type Operations

#### `pgm.createType( type_name, values )`

> Create a new data type - [postgres docs](http://www.postgresql.org/docs/current/static/sql-createtype.html)

Expand All @@ -371,6 +351,86 @@ e.g. `pgm.func('CURRENT_TIMESTAMP')` to use in `default` option for column defin

-----------------------------------------------------

### Role Operations

#### `pgm.createRole( role_name, role_options )`

> Create a new role - [postgres docs](http://www.postgresql.org/docs/current/static/sql-createrole.html)

**Arguments:**
- `role_name` _[string]_ - name of the new role
- `role_options` _[object]_ - options:
- `superuser` _[boolean]_ - default false
- `createdb` _[boolean]_ - default false
- `createrole` _[boolean]_ - default false
- `inherit` _[boolean]_ - default true
- `login` _[boolean]_ - default false
- `replication` _[boolean]_ - default false
- `bypassrls` _[boolean]_
- `limit` _[number]_ -
- `password` _[string]_ -
- `encrypted` _[boolean]_ - default true
- `valid` _[string]_ - timestamp
- `inRole` _[string or array]_ - role or array of roles
- `role` _[string or array]_ - role or array of roles
- `admin` _[string or array]_ - role or array of roles

**Reverse Operation:** `dropRole`

-----------------------------------------------------

#### `pgm.dropRole( role_name )`

> Drop a role - [postgres docs](http://www.postgresql.org/docs/current/static/sql-droprole.html)

**Arguments:**
- `role_name` _[string]_ - name of the new role

-----------------------------------------------------

#### `pgm.alterRole( role_name, role_options )`

> Alters a role - [postgres docs](http://www.postgresql.org/docs/current/static/sql-alterrole.html)

**Arguments:**
- `role_name` _[string]_ - name of the new role
- `role_options` _[object]_ - [see](#pgmcreaterole-role_name-role_options-)

-----------------------------------------------------

#### `pgm.renameRole( old_role_name, new_role_name )`

> Alters a role - [postgres docs](http://www.postgresql.org/docs/current/static/sql-alterrole.html)

**Arguments:**
- `old_role_name` _[string]_ - old name of the role
- `new_role_name` _[string]_ - new name of the role

-----------------------------------------------------

### Miscellaneous Operations

#### `pgm.sql( sql )`

> Run raw sql -- with some optional _[very basic](http://mir.aculo.us/2011/03/09/little-helpers-a-tweet-sized-javascript-templating-engine/)_ mustache templating

**Arguments:**
- `sql` _[string]_ - SQL query to run
- `args` _[object]_ - (optional) key/val of arguments to replace

-----------------------------------------------------

#### `pgm.func( sql )`

> Inserts raw string, which is not escaped

e.g. `pgm.func('CURRENT_TIMESTAMP')` to use in `default` option for column definition

**Arguments:**
- `sql` _[string]_ - string to not be escaped

-----------------------------------------------------

### Column Definitions

The `createTable` and `addColumns` methods both take a `columns` argument that specifies column names and options. It is a object (key/value) where each key is the name of the column, and the value is another object that defines the options for the column.
Expand Down
6 changes: 6 additions & 0 deletions lib/migration-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { PgLiteral } from './utils';
import * as extensions from './operations/extensions';
import * as indexes from './operations/indexes';
import * as tables from './operations/tables';
import * as roles from './operations/roles';
import * as other from './operations/other';

export default class MigrationBuilder {
Expand Down Expand Up @@ -69,6 +70,11 @@ export default class MigrationBuilder {
this.dropIndex = wrap(indexes.drop);
this.addIndex = this.createIndex;

this.createRole = wrap(roles.create);
this.dropRole = wrap(roles.drop);
this.alterRole = wrap(roles.alter);
this.renameRole = wrap(roles.rename);

this.sql = wrap(other.sql);

// Other utilities which may be useful
Expand Down
57 changes: 57 additions & 0 deletions lib/operations/roles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { isArray } from 'lodash';
import { template, escapeValue } from '../utils';

const formatRoleOptions = (role_options = {}) => {
const options = [];
options.push(role_options.superuser ? 'SUPERUSER' : 'NOSUPERUSER');
options.push(role_options.createdb ? 'CREATEDB' : 'NOCREATEDB');
options.push(role_options.createrole ? 'CREATEROLE' : 'NOCREATEROLE');
options.push(!role_options.inherit ? 'NOINHERIT' : 'INHERIT');
options.push(role_options.login ? 'LOGIN' : 'NOLOGIN');
options.push(role_options.replication ? 'REPLICATION' : 'NOREPLICATION');
if (role_options.bypassrls !== undefined) {
options.push(role_options.bypassrls ? 'BYPASSRLS' : 'NOBYPASSRLS');
}
if (role_options.limit) {
options.push(`CONNECTION LIMIT ${Number(role_options.limit)}`);
}
if (role_options.password) {
options.push(`${!role_options.encrypted ? 'UNENCRYPTED' : 'ENCRYPTED'} PASSWORD ${escapeValue(role_options.password)}`);
}
if (role_options.valid) {
options.push(`VALID UNTIL ${escapeValue(role_options.valid)}`);
}
if (role_options.inRole) {
options.push(`IN ROLE ${isArray(role_options.inRole) ? role_options.inRole.join(',') : role_options.inRole}`);
}
if (role_options.role) {
options.push(`ROLE ${isArray(role_options.role) ? role_options.role.join(',') : role_options.role}`);
}
if (role_options.admin) {
options.push(`IN ROLE ${isArray(role_options.admin) ? role_options.admin.join(',') : role_options.admin}`);
}

return options.join(' ');
};

export const create = (role_name, role_options = {}) => {
const options = formatRoleOptions(role_options);
return template`CREATE ROLE ${role_name}${options ? ` WITH ${options}` : ''};`;
};

export const drop = role_name => `DROP ROLE "${role_name}";`;

export const alter = (role_name, role_options = {}) => {
const options = formatRoleOptions(role_options);
return template`ALTER ROLE ${role_name}${options ? ` WITH ${options}` : ''};`;
};

export const rename = (old_role_name, new_role_name) =>
template`ALTER ROLE ${old_role_name} RENAME TO ${new_role_name};`;

export const undoRename = (old_role_name, new_role_name) =>
rename(new_role_name, old_role_name);

// setup reverse functions
create.reverse = drop;
rename.reverse = undoRename;