Ctrl K
ComunidadGuías…

packages/sql/catalog.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import type { NameCase } from './dialect'

export interface SqlColumn {
  name: string
  type: string
  nullable: boolean
  comment?: string | null
}

export interface SqlTable {
  name: string
  kind: string
  /** `null` while the columns have not been loaded — column checks and suggestions skip the table. */
  columns: SqlColumn[] | null
  comment?: string | null
}

interface SqlSchema {
  name: string
  tables: SqlTable[]
}

interface SqlEnum {
  name: string
  values: string[]
  table?: string
  column?: string
}

export interface SqlCatalog {
  defaultSchema: string | null
  nameCase: NameCase | null
  schemas: SqlSchema[]
  enums: SqlEnum[]
}

const collator = new Intl.Collator(undefined, { sensitivity: 'accent' })

const namesMatch = (catalog: SqlCatalog, a: string, b: string) =>
  catalog.nameCase ? a === b : collator.compare(a, b) === 0

export const findSchema = (catalog: SqlCatalog, name: string) =>
  catalog.schemas.find((schema) => namesMatch(catalog, schema.name, name))

export const findTableWithSchema = (
  catalog: SqlCatalog,
  name: string,
  schema: string | null
) => {
  const schemas = schema
    ? [findSchema(catalog, schema)]
    : [
        ...(catalog.defaultSchema
          ? [findSchema(catalog, catalog.defaultSchema)]
          : []),
        ...catalog.schemas,
      ]
  for (const candidate of schemas) {
    const table = candidate?.tables.find((item) =>
      namesMatch(catalog, item.name, name)
    )
    if (candidate && table) {
      return { schema: candidate.name, table }
    }
  }
}

export const findTable = (
  catalog: SqlCatalog,
  name: string,
  schema: string | null
) => findTableWithSchema(catalog, name, schema)?.table

export const findColumn = (
  catalog: SqlCatalog,
  table: SqlTable,
  name: string
) => table.columns?.find((column) => namesMatch(catalog, column.name, name))

export const findEnum = (
  catalog: SqlCatalog,
  table: string,
  column: SqlColumn
) =>
  catalog.enums.find(
    (item) => item.table === table && item.column === column.name
  ) ??
  catalog.enums.find(
    (item) =>
      collator.compare(item.name, column.type) === 0 ||
      column.type.toLowerCase().endsWith(`.${item.name.toLowerCase()}`)
  )