Skip to content
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
8 changes: 5 additions & 3 deletions docs/src/migrations/tables.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
| `constraints` | `object` | table constraints see `expression` of [add constraint](constraints.md#pgmaddconstraint-tablename-constraint_name-expression-) |
| `like` | [Name](/migrations/#type) or `object` | table(s) to inherit from or object with `table` and `options` keys |
| `comment` | `string` | adds comment on table |
| `unlogged` | `boolean` | default `false` |

#### like options

Expand Down Expand Up @@ -86,6 +87,7 @@

### Options

| Option | Type | Description |
| --------------- | -------- | ------------------------------------------- |
| `levelSecurity` | `string` | `DISABLE`, `ENABLE`, `FORCE`, or `NO FORCE` |
| Option | Type | Description |
| --------------- | --------- | ------------------------------------------- |
| `levelSecurity` | `string` | `DISABLE`, `ENABLE`, `FORCE`, or `NO FORCE` |
| `unlogged` | `boolean` | Sets UNLOGGED if true |
11 changes: 9 additions & 2 deletions src/operations/tables/alterTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { formatLines } from '../../utils';
import type { Name } from '../generalTypes';

export interface AlterTableOptions {
levelSecurity: 'DISABLE' | 'ENABLE' | 'FORCE' | 'NO FORCE';
levelSecurity?: 'DISABLE' | 'ENABLE' | 'FORCE' | 'NO FORCE';
unlogged?: boolean;
}

export type AlterTable = (
Expand All @@ -13,14 +14,20 @@ export type AlterTable = (

export function alterTable(mOptions: MigrationOptions): AlterTable {
const _alter: AlterTable = (tableName, options) => {
const { levelSecurity } = options;
const { levelSecurity, unlogged } = options;

const alterDefinition: string[] = [];

if (levelSecurity) {
alterDefinition.push(`${levelSecurity} ROW LEVEL SECURITY`);
}

if (unlogged === true) {
alterDefinition.push(`SET UNLOGGED`);
} else if (unlogged === false) {
alterDefinition.push(`SET LOGGED`);
}

return `ALTER TABLE ${mOptions.literal(tableName)}
${formatLines(alterDefinition)};`;
};
Expand Down
8 changes: 7 additions & 1 deletion src/operations/tables/createTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export function createTable(mOptions: MigrationOptions): CreateTable {
constraints: optionsConstraints = {},
comment,
partition,
unlogged = false,
} = options;

const {
Expand Down Expand Up @@ -65,7 +66,12 @@ export function createTable(mOptions: MigrationOptions): CreateTable {
...(like ? [parseLike(like, mOptions.literal)] : []),
];

if (temporary && unlogged) {
throw new Error('TEMPORARY and UNLOGGED cannot be used together.');
}

const temporaryStr = temporary ? ' TEMPORARY' : '';
const unloggedStr = unlogged ? ' UNLOGGED' : '';
const ifNotExistsStr = ifNotExists ? ' IF NOT EXISTS' : '';
const inheritsStr = inherits
? ` INHERITS (${mOptions.literal(inherits)})`
Expand All @@ -77,7 +83,7 @@ export function createTable(mOptions: MigrationOptions): CreateTable {

const tableNameStr = mOptions.literal(tableName);

const createTableQuery = `CREATE${temporaryStr} TABLE${ifNotExistsStr} ${tableNameStr} (
const createTableQuery = `CREATE${temporaryStr}${unloggedStr} TABLE${ifNotExistsStr} ${tableNameStr} (
${formatLines(tableDefinition)}
)${inheritsStr}${partitionStr};`;
const comments = [...columnComments, ...constraintComments];
Expand Down
2 changes: 2 additions & 0 deletions src/operations/tables/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ export interface TableOptions extends IfNotExistsOption {
comment?: string | null;

partition?: PartitionOptions;

unlogged?: boolean;
}

export function parseReferences(
Expand Down
8 changes: 4 additions & 4 deletions test/migration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ describe('migration', () => {
const filePaths = await getMigrationFilePaths(dir, { logger });

expect(Array.isArray(filePaths)).toBeTruthy();
expect(filePaths).toHaveLength(93);
expect(filePaths).toHaveLength(94);
expect(filePaths).not.toContainEqual(expect.stringContaining('nested'));

for (const filePath of filePaths) {
Expand All @@ -83,7 +83,7 @@ describe('migration', () => {
});

expect(Array.isArray(filePaths)).toBeTruthy();
expect(filePaths).toHaveLength(68);
expect(filePaths).toHaveLength(69);

for (const filePath of filePaths) {
expect(isAbsolute(filePath)).toBeTruthy();
Expand All @@ -99,7 +99,7 @@ describe('migration', () => {
});

expect(Array.isArray(filePaths)).toBeTruthy();
expect(filePaths).toHaveLength(106);
expect(filePaths).toHaveLength(107);
expect(filePaths).toContainEqual(expect.stringContaining('nested'));

for (const filePath of filePaths) {
Expand All @@ -119,7 +119,7 @@ describe('migration', () => {
});

expect(Array.isArray(filePaths)).toBeTruthy();
expect(filePaths).toHaveLength(105);
expect(filePaths).toHaveLength(106);
expect(filePaths).toContainEqual(expect.stringContaining('nested'));

for (const filePath of filePaths) {
Expand Down
43 changes: 43 additions & 0 deletions test/migrations/094_unlogged_table.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
export const comment = 'comment on unlogged table t_unlogged';

export const up = (pgm) => {
// Create an unlogged table
pgm.createTable(
't_unlogged',
{
id: 'id',
name: { type: 'text', notNull: true },
created_at: {
type: 'timestamp',
notNull: true,
default: pgm.func('current_timestamp'),
},
},
{
unlogged: true, // Specify the table as UNLOGGED
comment,
}
);

// Create a regular table for comparison
pgm.createTable(
't_regular',
{
id: 'id',
description: { type: 'text', notNull: true },
},
{
comment: 'comment on regular table t_regular',
}
);

// Alter the regular table to set it as LOGGED
pgm.alterTable('t_regular', {
unlogged: false,
});
};

export const down = (pgm) => {
pgm.dropTable('t_unlogged');
pgm.dropTable('t_regular');
};
26 changes: 21 additions & 5 deletions test/operations/tables/alterTable.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@ describe('operations', () => {

// TODO @Shinigami92 2024-03-11: This should throw an error
it('should return sql statement', () => {
const statement = alterTableFn(
'films',
// @ts-expect-error: add runtime error
{}
);
const statement = alterTableFn('films', {});

expect(statement).toBeTypeOf('string');
expect(statement).toBe(`ALTER TABLE "films"
Expand All @@ -33,6 +29,26 @@ describe('operations', () => {
expect(statement).toBe(`ALTER TABLE "distributors"
ENABLE ROW LEVEL SECURITY;`);
});

it('should generate SQL for SET LOGGED', () => {
const statement = alterTableFn('my_table', {
unlogged: false,
});

expect(statement).toBeTypeOf('string');
expect(statement).toBe(`ALTER TABLE "my_table"
SET LOGGED;`);
});

it('should generate SQL for SET UNLOGGED', () => {
const statement = alterTableFn('my_table', {
unlogged: true,
});

expect(statement).toBeTypeOf('string');
expect(statement).toBe(`ALTER TABLE "my_table"
SET UNLOGGED;`);
});
});
});
});
10 changes: 10 additions & 0 deletions test/operations/tables/createTable.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,16 @@ COMMENT ON CONSTRAINT "fk_col_b" ON "my_table_name" IS $pga$fk b comment$pga$;`,
],
new Error('cannot comment on unspecified constraints'),
],
[
'should throw on using both temporary and unlogged options',
options1,
[
'myTableName',
{ colA: { type: 'integer' } },
{ temporary: true, unlogged: true },
],
new Error('TEMPORARY and UNLOGGED cannot be used together.'),
],
] as const)(
'%s',
(_, optionPreset, [tableName, columns, options], expected) => {
Expand Down