Files
supabase/apps/studio/data/fdw/fdw-import-foreign-schema-mutation.ts
Ivan Vasilov c5bf65b0b4 feat: Create FDW for S3 Vectors buckets (#40206)
* Fix childProps in Admonition so that they're added as a prop to the main div.

* Replace the admonition with Alert in Wrapper tab page to add a gap between childs.

* Add s3 vectors fdw.

* Minor fix to FormSection.

* Update the fdw mutations to support passing in options.

* Refactor the vector flow to create fdws.

* Revert cron description change.

* If the bucket can't be created, don't create a fdw.

* Update/delete the fdw when deleting a table or a bucket.

* Minor fixes.

* Clean up the delete modal.

* Handle edge cases when missing a wrapper.

* Remove the admonition in the create bucket modal.

* Fix the loading state when creating a bucket.

* Fix the createWrapper sheet to work with s3 vectors.

* Fix undefined wrapperMeta issue.

* Create the schema when installing a wrapper.

* Tiny cleanup.

* Clean up unneeded useState. Create a wrapper only if the all conditions are met.

* Fix all comments.

* Add s3 vectors for docs.

* Add a link and fix the file name for S3 Vectors in docs.

* Hide the table editor button if the wrapper instance is missing.

* Small fixes.
2025-11-12 11:00:38 +01:00

82 lines
2.6 KiB
TypeScript

import { useMutation, useQueryClient } from '@tanstack/react-query'
import { toast } from 'sonner'
import { entityTypeKeys } from 'data/entity-types/keys'
import { foreignTableKeys } from 'data/foreign-tables/keys'
import { executeSql } from 'data/sql/execute-sql-query'
import { wrapWithTransaction } from 'data/sql/utils/transaction'
import { vaultSecretsKeys } from 'data/vault/keys'
import type { ResponseError, UseCustomMutationOptions } from 'types'
import { fdwKeys } from './keys'
export type FDWImportForeignSchemaVariables = {
projectRef?: string
connectionString?: string | null
serverName: string
sourceSchema: string
targetSchema: string
schemaOptions?: string[]
}
export function getImportForeignSchemaSql({
serverName,
sourceSchema,
targetSchema,
schemaOptions = [],
}: Omit<FDWImportForeignSchemaVariables, 'projectRef' | 'connectionString'>) {
const options = [...schemaOptions, "strict 'true'"].join(', ')
const sql = /* SQL */ `
import foreign schema "${sourceSchema}" from server ${serverName} into ${targetSchema} options (${options});
`
return sql
}
export async function importForeignSchema({
projectRef,
connectionString,
...rest
}: FDWImportForeignSchemaVariables) {
const sql = wrapWithTransaction(getImportForeignSchemaSql(rest))
const { result } = await executeSql({ projectRef, connectionString, sql })
return result
}
type ImportForeignSchemaData = Awaited<ReturnType<typeof importForeignSchema>>
export const useFDWImportForeignSchemaMutation = ({
onSuccess,
onError,
...options
}: Omit<
UseCustomMutationOptions<ImportForeignSchemaData, ResponseError, FDWImportForeignSchemaVariables>,
'mutationFn'
> = {}) => {
const queryClient = useQueryClient()
return useMutation<ImportForeignSchemaData, ResponseError, FDWImportForeignSchemaVariables>({
mutationFn: (vars) => importForeignSchema(vars),
async onSuccess(data, variables, context) {
const { projectRef } = variables
await Promise.all([
queryClient.invalidateQueries({ queryKey: fdwKeys.list(projectRef), refetchType: 'all' }),
queryClient.invalidateQueries({ queryKey: entityTypeKeys.list(projectRef) }),
queryClient.invalidateQueries({ queryKey: foreignTableKeys.list(projectRef) }),
queryClient.invalidateQueries({ queryKey: vaultSecretsKeys.list(projectRef) }),
])
await onSuccess?.(data, variables, context)
},
async onError(data, variables, context) {
if (onError === undefined) {
toast.error(`Failed to import schema for foreign data wrapper: ${data.message}`)
} else {
onError(data, variables, context)
}
},
...options,
})
}