Skip to content

Commit

Permalink
refactor(views): reorganize operations views (#1085)
Browse files Browse the repository at this point in the history
  • Loading branch information
Shinigami92 committed Apr 11, 2024
1 parent 4e9ad08 commit c786932
Show file tree
Hide file tree
Showing 11 changed files with 237 additions and 226 deletions.
23 changes: 13 additions & 10 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,19 @@ export type {
RenameTypeValueFn,
SetTypeAttribute,
} from './operations/types';
export type {
AlterView,
AlterViewColumn,
AlterViewColumnOptions,
AlterViewOptions,
CreateView,
CreateViewFn,
CreateViewOptions,
DropView,
RenameView,
RenameViewFn,
ViewOptions,
} from './operations/views';
export type {
AlterMaterializedView,
AlterMaterializedViewOptions,
Expand All @@ -175,16 +188,6 @@ export type {
RenameMaterializedView,
RenameMaterializedViewColumn,
} from './operations/viewsMaterializedTypes';
export type {
AlterView,
AlterViewColumn,
AlterViewColumnOptions,
AlterViewOptions,
CreateView,
CreateViewOptions,
DropView,
RenameView,
} from './operations/viewsTypes';
export { PgType } from './types';
export type { MigrationBuilder, RunnerOption } from './types';

Expand Down
160 changes: 0 additions & 160 deletions src/operations/views.ts

This file was deleted.

55 changes: 55 additions & 0 deletions src/operations/views/alterView.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import type { MigrationOptions } from '../../types';
import type { Name, Nullable } from '../generalTypes';
import type { ViewOptions } from './shared';
import { viewOptionStr } from './shared';

export type AlterView = (
viewName: Name,
options: AlterViewOptions
) => string | string[];

export interface AlterViewOptions {
checkOption?: null | 'CASCADED' | 'LOCAL';

options?: Nullable<ViewOptions>;
}

export function alterView(mOptions: MigrationOptions): AlterView {
const _alter: AlterView = (viewName, viewOptions) => {
const { checkOption, options = {} } = viewOptions;

if (checkOption !== undefined) {
if (options.check_option === undefined) {
options.check_option = checkOption;
} else {
throw new Error(
'"options.check_option" and "checkOption" can\'t be specified together'
);
}
}

const clauses: string[] = [];
const withOptions = Object.keys(options)
.filter((key) => options[key] !== null)
.map(viewOptionStr(options))
.join(', ');

if (withOptions) {
clauses.push(`SET (${withOptions})`);
}

const resetOptions = Object.keys(options)
.filter((key) => options[key] === null)
.join(', ');

if (resetOptions) {
clauses.push(`RESET (${resetOptions})`);
}

return clauses
.map((clause) => `ALTER VIEW ${mOptions.literal(viewName)} ${clause};`)
.join('\n');
};

return _alter;
}
39 changes: 39 additions & 0 deletions src/operations/views/alterViewColumn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { MigrationOptions } from '../../types';
import { escapeValue } from '../../utils';
import type { Name, Value } from '../generalTypes';

export interface AlterViewColumnOptions {
default?: Value;
}

export type AlterViewColumn = (
viewName: Name,
columnName: string,
options: AlterViewColumnOptions
) => string | string[];

export function alterViewColumn(mOptions: MigrationOptions): AlterViewColumn {
const _alter: AlterViewColumn = (viewName, columnName, options) => {
const { default: defaultValue } = options;

const actions: string[] = [];

if (defaultValue === null) {
actions.push('DROP DEFAULT');
} else if (defaultValue !== undefined) {
actions.push(`SET DEFAULT ${escapeValue(defaultValue)}`);
}

const viewNameStr = mOptions.literal(viewName);
const columnNameStr = mOptions.literal(columnName);

return actions
.map(
(action) =>
`ALTER VIEW ${viewNameStr} ALTER COLUMN ${columnNameStr} ${action};`
)
.join('\n');
};

return _alter;
}
63 changes: 63 additions & 0 deletions src/operations/views/createView.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import type { MigrationOptions } from '../../types';
import type { DropOptions, Name } from '../generalTypes';
import { dropView } from './dropView';
import type { ViewOptions } from './shared';
import { viewOptionStr } from './shared';

export interface CreateViewOptions {
temporary?: boolean;

replace?: boolean;

recursive?: boolean;

columns?: string | string[];

checkOption?: 'CASCADED' | 'LOCAL';

options?: ViewOptions;
}

export type CreateViewFn = (
viewName: Name,
options: CreateViewOptions & DropOptions,
definition: string
) => string | string[];

export type CreateView = CreateViewFn & { reverse: CreateViewFn };

export function createView(mOptions: MigrationOptions): CreateView {
const _create: CreateView = (viewName, viewOptions, definition) => {
const {
temporary,
replace,
recursive,
columns = [],
options = {},
checkOption,
} = viewOptions;

const columnNames = (Array.isArray(columns) ? columns : [columns])
.map(mOptions.literal)
.join(', ');
const withOptions = Object.keys(options)
.map(viewOptionStr(options))
.join(', ');

const replaceStr = replace ? ' OR REPLACE' : '';
const temporaryStr = temporary ? ' TEMPORARY' : '';
const recursiveStr = recursive ? ' RECURSIVE' : '';
const columnStr = columnNames ? `(${columnNames})` : '';
const withOptionsStr = withOptions ? ` WITH (${withOptions})` : '';
const checkOptionStr = checkOption
? ` WITH ${checkOption} CHECK OPTION`
: '';
const viewNameStr = mOptions.literal(viewName);

return `CREATE${replaceStr}${temporaryStr}${recursiveStr} VIEW ${viewNameStr}${columnStr}${withOptionsStr} AS ${definition}${checkOptionStr};`;
};

_create.reverse = dropView(mOptions);

return _create;
}
21 changes: 21 additions & 0 deletions src/operations/views/dropView.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { MigrationOptions } from '../../types';
import type { DropOptions, Name } from '../generalTypes';

export type DropView = (
viewName: Name,
options?: DropOptions
) => string | string[];

export function dropView(mOptions: MigrationOptions): DropView {
const _drop: DropView = (viewName, options = {}) => {
const { ifExists, cascade } = options;

const ifExistsStr = ifExists ? ' IF EXISTS' : '';
const cascadeStr = cascade ? ' CASCADE' : '';
const viewNameStr = mOptions.literal(viewName);

return `DROP VIEW${ifExistsStr} ${viewNameStr}${cascadeStr};`;
};

return _drop;
}
6 changes: 6 additions & 0 deletions src/operations/views/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export * from './alterView';
export * from './alterViewColumn';
export * from './createView';
export * from './dropView';
export * from './renameView';
export * from './shared';
Loading

0 comments on commit c786932

Please sign in to comment.