| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- import { source } from 'common-tags'
- import { executeQuery } from './query'
- import { PgMetaDatabaseError, WrappedResult } from './types'
- import { assertSelfHosted } from './util'
- import { makeRandomString } from '@/lib/helpers'
- export type ListMigrationsResult = {
- version: string
- name?: string
- }
- const listMigrationVersionsQuery = () =>
- 'select version, name from briven_migrations.schema_migrations order by version'
- const initializeHistoryTableQuery = () => `begin;
- create schema if not exists briven_migrations;
- create table if not exists briven_migrations.schema_migrations (version text not null primary key);
- alter table briven_migrations.schema_migrations add column if not exists statements text[];
- alter table briven_migrations.schema_migrations add column if not exists name text;
- commit;`
- const applyAndTrackMigrationsQuery = (query: string, name?: string) => {
- // Escapes literals using postgres dollar quoted string
- const dollar = `$${makeRandomString(20)}$`
- const quote = (s?: string) => (s ? dollar + s + dollar : `''`)
- return source`
- begin;
- -- apply sql from post body
- ${query};
- -- track statements in history table
- insert into briven_migrations.schema_migrations (version, name, statements)
- values (
- to_char(current_timestamp, 'YYYYMMDDHH24MISS'),
- ${quote(name)},
- array[${quote(query)}]
- );
- commit;
- `
- }
- export type ListMigrationVersionsOptions = {
- headers?: HeadersInit
- }
- /**
- * Lists all migrations in the migrations history table.
- *
- * _Only call this from server-side self-hosted code._
- */
- export async function listMigrationVersions({
- headers,
- }: ListMigrationVersionsOptions): Promise<WrappedResult<ListMigrationsResult[]>> {
- assertSelfHosted()
- const { data, error } = await executeQuery<ListMigrationsResult>({
- query: listMigrationVersionsQuery(),
- headers,
- })
- if (error) {
- // Return empty list if the migrations table doesn't exist
- if (error instanceof PgMetaDatabaseError && error.code === '42P01') {
- return { data: [], error: undefined }
- }
- return { data: undefined, error }
- }
- return { data, error: undefined }
- }
- export type ApplyAndTrackMigrationsOptions = {
- query: string
- name?: string
- headers?: HeadersInit
- }
- /**
- * Applies a SQL migration and tracks it in the migrations history table.
- *
- * _Only call this from server-side self-hosted code._
- */
- export async function applyAndTrackMigrations<T = unknown>({
- query,
- name,
- headers,
- }: ApplyAndTrackMigrationsOptions): Promise<WrappedResult<T[]>> {
- assertSelfHosted()
- const initializeResponse = await executeQuery<void>({
- query: initializeHistoryTableQuery(),
- headers,
- })
- if (initializeResponse.error) {
- return initializeResponse
- }
- const applyAndTrackResponse = await executeQuery<T>({
- query: applyAndTrackMigrationsQuery(query, name),
- headers,
- })
- return applyAndTrackResponse
- }
|