import pgMeta from '@supabase/pg-meta' import { PGColumn } from '@supabase/pg-meta/src/pg-meta-columns' import { useMutation, useQueryClient } from '@tanstack/react-query' import { toast } from 'sonner' import { databaseKeys } from 'data/database/keys' import { entityTypeKeys } from 'data/entity-types/keys' import { executeSql } from 'data/sql/execute-sql-query' import { tableEditorKeys } from 'data/table-editor/keys' import { tableRowKeys } from 'data/table-rows/keys' import { viewKeys } from 'data/views/keys' import type { ResponseError, UseCustomMutationOptions } from 'types' export type DatabaseColumnDeleteVariables = { projectRef: string connectionString?: string | null column: Pick cascade?: boolean } export async function deleteDatabaseColumn({ projectRef, connectionString, column, cascade = false, }: DatabaseColumnDeleteVariables) { const { sql } = pgMeta.columns.remove(column, { cascade }) const { result } = await executeSql({ projectRef, connectionString, sql, queryKey: ['column', 'delete', column.id], }) return result } type DatabaseColumnDeleteData = Awaited> export const useDatabaseColumnDeleteMutation = ({ onSuccess, onError, ...options }: Omit< UseCustomMutationOptions, 'mutationFn' > = {}) => { const queryClient = useQueryClient() return useMutation({ mutationFn: (vars) => deleteDatabaseColumn(vars), async onSuccess(data, variables, context) { const { projectRef, column } = variables await Promise.all([ // refetch all entities in the sidebar because deleting a column may regenerate a view (and change its id) queryClient.invalidateQueries({ queryKey: entityTypeKeys.list(projectRef) }), queryClient.invalidateQueries({ queryKey: databaseKeys.foreignKeyConstraints(projectRef, column.schema), }), queryClient.invalidateQueries({ queryKey: tableEditorKeys.tableEditor(projectRef, column.table_id), }), queryClient.invalidateQueries({ queryKey: databaseKeys.tableDefinition(projectRef, column.table_id), }), // invalidate all views from this schema, not sure if this is needed since you can't actually delete a column // which has a view dependent on it queryClient.invalidateQueries({ queryKey: viewKeys.listBySchema(projectRef, column.schema), }), ]) // We need to invalidate tableRowsAndCount after tableEditor // to ensure the query sent is correct await queryClient.invalidateQueries({ queryKey: tableRowKeys.tableRowsAndCount(projectRef, column.table_id), }) await onSuccess?.(data, variables, context) }, async onError(data, variables, context) { if (onError === undefined) { toast.error(`Failed to delete database column: ${data.message}`) } else { onError(data, variables, context) } }, ...options, }) }