mirror of
https://github.com/supabase/supabase.git
synced 2026-09-06 09:59:03 +08:00
## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Bug fix ## What is the current behavior? Fixes stale table metadata after saving edits from the table editor drawer. Previously, metadata-only table changes, such as column updates, primary key/foreign key changes, table renames, or schema moves, could leave cached table data stale. This affected the Database tables list, schema visualizer, and reopening the edit drawer. Fixes #47540 ## What is the new behavior? Table metadata caches are now invalidated consistently after table create, update, delete, column delete, and queue table creation flows. The Database tables list, schema visualizer, table editor drawer, table definitions, constraints, foreign keys, table columns, rows, and lint data now refresh correctly after relevant table metadata changes. ## Additional context https://github.com/user-attachments/assets/de849710-8d7b-4d8b-af3b-5232154e996b <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Table metadata now refreshes consistently after table creation, updates, duplication, and deletion. * **Bug Fixes** * Improved synchronization for table lists, lint results, constraints, and row counts after changes. * Renaming or moving tables now refreshes both the previous and updated locations. * Column and queue changes now trigger the appropriate table metadata updates. * **Tests** * Added coverage for metadata refresh behavior across edits, moves, optional lint updates, and row counts. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Ali Waseem <waseema393@gmail.com>
80 lines
2.5 KiB
TypeScript
80 lines
2.5 KiB
TypeScript
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 { executeSql } from '@/data/sql/execute-sql-mutation'
|
|
import { invalidateTableMetadata } from '@/data/tables/table-metadata-invalidation'
|
|
import { viewKeys } from '@/data/views/keys'
|
|
import type { ResponseError, UseCustomMutationOptions } from '@/types'
|
|
|
|
export type DatabaseColumnDeleteVariables = {
|
|
projectRef: string
|
|
connectionString?: string | null
|
|
column: Pick<PGColumn, 'id' | 'name' | 'schema' | 'table' | 'table_id'>
|
|
cascade?: boolean
|
|
}
|
|
|
|
export async function deleteDatabaseColumn({
|
|
projectRef,
|
|
connectionString,
|
|
column,
|
|
cascade = false,
|
|
}: DatabaseColumnDeleteVariables) {
|
|
const { sql } = pgMeta.columns.remove(column, { cascade })
|
|
|
|
const { result } = await executeSql<void>({
|
|
projectRef,
|
|
connectionString,
|
|
sql,
|
|
queryKey: ['column', 'delete', column.id],
|
|
})
|
|
|
|
return result
|
|
}
|
|
|
|
type DatabaseColumnDeleteData = Awaited<ReturnType<typeof deleteDatabaseColumn>>
|
|
|
|
export const useDatabaseColumnDeleteMutation = ({
|
|
onSuccess,
|
|
onError,
|
|
...options
|
|
}: Omit<
|
|
UseCustomMutationOptions<DatabaseColumnDeleteData, ResponseError, DatabaseColumnDeleteVariables>,
|
|
'mutationFn'
|
|
> = {}) => {
|
|
const queryClient = useQueryClient()
|
|
return useMutation<DatabaseColumnDeleteData, ResponseError, DatabaseColumnDeleteVariables>({
|
|
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)
|
|
invalidateTableMetadata(queryClient, {
|
|
projectRef,
|
|
schema: column.schema,
|
|
tableId: column.table_id,
|
|
tableName: column.table,
|
|
includeRows: true,
|
|
includeLint: true,
|
|
}),
|
|
// 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]),
|
|
}),
|
|
])
|
|
|
|
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,
|
|
})
|
|
}
|