Skip to content

Commit

Permalink
Merge pull request #685 from isaacharrisholt/chore/refactor-generator…
Browse files Browse the repository at this point in the history
…-metadata-collection

chore(typegen): Extract metadata generation to function
  • Loading branch information
soedirgo authored Mar 12, 2024
2 parents d8bfcc4 + 536f8c1 commit 0dbbdb6
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 98 deletions.
118 changes: 118 additions & 0 deletions src/lib/generators.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import PostgresMeta from './PostgresMeta.js'
import {
PostgresColumn,
PostgresFunction,
PostgresMaterializedView,
PostgresRelationship,
PostgresSchema,
PostgresTable,
PostgresType,
PostgresView,
} from './types.js'
import { PostgresMetaResult } from './types.js'

export type GeneratorMetadata = {
schemas: PostgresSchema[]
tables: Omit<PostgresTable, 'columns'>[]
views: Omit<PostgresView, 'columns'>[]
materializedViews: Omit<PostgresMaterializedView, 'columns'>[]
columns: PostgresColumn[]
relationships: PostgresRelationship[]
functions: PostgresFunction[]
types: PostgresType[]
}

export async function getGeneratorMetadata(
pgMeta: PostgresMeta,
filters: { includedSchemas?: string[]; excludedSchemas?: string[] } = {
includedSchemas: [],
excludedSchemas: [],
}
): Promise<PostgresMetaResult<GeneratorMetadata>> {
const includedSchemas = filters.includedSchemas ?? []
const excludedSchemas = filters.excludedSchemas ?? []

const { data: schemas, error: schemasError } = await pgMeta.schemas.list()
if (schemasError) {
return { data: null, error: schemasError }
}

const { data: tables, error: tablesError } = await pgMeta.tables.list({
includedSchemas: includedSchemas.length > 0 ? includedSchemas : undefined,
excludedSchemas,
includeColumns: false,
})
if (tablesError) {
return { data: null, error: tablesError }
}

const { data: views, error: viewsError } = await pgMeta.views.list({
includedSchemas: includedSchemas.length > 0 ? includedSchemas : undefined,
excludedSchemas,
includeColumns: false,
})
if (viewsError) {
return { data: null, error: viewsError }
}

const { data: materializedViews, error: materializedViewsError } =
await pgMeta.materializedViews.list({
includedSchemas: includedSchemas.length > 0 ? includedSchemas : undefined,
excludedSchemas,
includeColumns: false,
})
if (materializedViewsError) {
return { data: null, error: materializedViewsError }
}

const { data: columns, error: columnsError } = await pgMeta.columns.list({
includedSchemas: includedSchemas.length > 0 ? includedSchemas : undefined,
excludedSchemas,
})
if (columnsError) {
return { data: null, error: columnsError }
}

const { data: relationships, error: relationshipsError } = await pgMeta.relationships.list()
if (relationshipsError) {
return { data: null, error: relationshipsError }
}

const { data: functions, error: functionsError } = await pgMeta.functions.list({
includedSchemas: includedSchemas.length > 0 ? includedSchemas : undefined,
excludedSchemas,
})
if (functionsError) {
return { data: null, error: functionsError }
}

const { data: types, error: typesError } = await pgMeta.types.list({
includeArrayTypes: true,
includeSystemSchemas: true,
})
if (typesError) {
return { data: null, error: typesError }
}

await pgMeta.end()

return {
data: {
schemas: schemas.filter(
({ name }) =>
!excludedSchemas.includes(name) &&
(includedSchemas.length === 0 || includedSchemas.includes(name))
),
tables,
views,
materializedViews,
columns,
relationships,
functions: functions.filter(
({ return_type }) => !['trigger', 'event_trigger'].includes(return_type)
),
types,
},
error: null,
}
}
92 changes: 7 additions & 85 deletions src/server/routes/generators/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { PostgresMeta } from '../../../lib/index.js'
import { DEFAULT_POOL_CONFIG } from '../../constants.js'
import { extractRequestForLogging } from '../../utils.js'
import { apply as applyTypescriptTemplate } from '../../templates/typescript.js'
import { getGeneratorMetadata } from '../../../lib/generators.js'

export default async (fastify: FastifyInstance) => {
fastify.get<{
Expand All @@ -21,97 +22,18 @@ export default async (fastify: FastifyInstance) => {
const detectOneToOneRelationships = request.query.detect_one_to_one_relationships === 'true'

const pgMeta: PostgresMeta = new PostgresMeta({ ...DEFAULT_POOL_CONFIG, connectionString })
const { data: schemas, error: schemasError } = await pgMeta.schemas.list()
const { data: tables, error: tablesError } = await pgMeta.tables.list({
includedSchemas: includedSchemas.length > 0 ? includedSchemas : undefined,
const { data: generatorMeta, error: generatorMetaError } = await getGeneratorMetadata(pgMeta, {
includedSchemas,
excludedSchemas,
includeColumns: false,
})
const { data: views, error: viewsError } = await pgMeta.views.list({
includedSchemas: includedSchemas.length > 0 ? includedSchemas : undefined,
excludedSchemas,
includeColumns: false,
})
const { data: materializedViews, error: materializedViewsError } =
await pgMeta.materializedViews.list({
includedSchemas: includedSchemas.length > 0 ? includedSchemas : undefined,
excludedSchemas,
includeColumns: false,
})
const { data: columns, error: columnsError } = await pgMeta.columns.list({
includedSchemas: includedSchemas.length > 0 ? includedSchemas : undefined,
excludedSchemas,
})
const { data: relationships, error: relationshipsError } = await pgMeta.relationships.list()
const { data: functions, error: functionsError } = await pgMeta.functions.list({
includedSchemas: includedSchemas.length > 0 ? includedSchemas : undefined,
excludedSchemas,
})
const { data: types, error: typesError } = await pgMeta.types.list({
includeArrayTypes: true,
includeSystemSchemas: true,
})
await pgMeta.end()

if (schemasError) {
request.log.error({ error: schemasError, request: extractRequestForLogging(request) })
reply.code(500)
return { error: schemasError.message }
}
if (tablesError) {
request.log.error({ error: tablesError, request: extractRequestForLogging(request) })
reply.code(500)
return { error: tablesError.message }
}
if (viewsError) {
request.log.error({ error: viewsError, request: extractRequestForLogging(request) })
reply.code(500)
return { error: viewsError.message }
}
if (materializedViewsError) {
request.log.error({
error: materializedViewsError,
request: extractRequestForLogging(request),
})
reply.code(500)
return { error: materializedViewsError.message }
}
if (columnsError) {
request.log.error({ error: columnsError, request: extractRequestForLogging(request) })
reply.code(500)
return { error: columnsError.message }
}
if (relationshipsError) {
request.log.error({ error: relationshipsError, request: extractRequestForLogging(request) })
reply.code(500)
return { error: relationshipsError.message }
}
if (functionsError) {
request.log.error({ error: functionsError, request: extractRequestForLogging(request) })
reply.code(500)
return { error: functionsError.message }
}
if (typesError) {
request.log.error({ error: typesError, request: extractRequestForLogging(request) })
if (generatorMetaError) {
request.log.error({ error: generatorMetaError, request: extractRequestForLogging(request) })
reply.code(500)
return { error: typesError.message }
return { error: generatorMetaError.message }
}

return applyTypescriptTemplate({
schemas: schemas.filter(
({ name }) =>
!excludedSchemas.includes(name) &&
(includedSchemas.length === 0 || includedSchemas.includes(name))
),
tables,
views,
materializedViews,
columns,
relationships,
functions: functions.filter(
({ return_type }) => !['trigger', 'event_trigger'].includes(return_type)
),
types,
...generatorMeta,
detectOneToOneRelationships,
})
})
Expand Down
15 changes: 2 additions & 13 deletions src/server/templates/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@ import prettier from 'prettier'
import type {
PostgresColumn,
PostgresFunction,
PostgresMaterializedView,
PostgresRelationship,
PostgresSchema,
PostgresTable,
PostgresType,
PostgresView,
} from '../../lib/index.js'
import type { GeneratorMetadata } from '../../lib/generators.js'

export const apply = async ({
schemas,
Expand All @@ -20,15 +17,7 @@ export const apply = async ({
functions,
types,
detectOneToOneRelationships,
}: {
schemas: PostgresSchema[]
tables: Omit<PostgresTable, 'columns'>[]
views: Omit<PostgresView, 'columns'>[]
materializedViews: Omit<PostgresMaterializedView, 'columns'>[]
columns: PostgresColumn[]
relationships: PostgresRelationship[]
functions: PostgresFunction[]
types: PostgresType[]
}: GeneratorMetadata & {
detectOneToOneRelationships: boolean
}): Promise<string> => {
const columnsByTableId = Object.fromEntries<PostgresColumn[]>(
Expand Down

0 comments on commit 0dbbdb6

Please sign in to comment.