diff --git a/apps/studio/data/database-extensions/database-extension-disable-mutation.ts b/apps/studio/data/database-extensions/database-extension-disable-mutation.ts index c126cdbf030..241be5740bd 100644 --- a/apps/studio/data/database-extensions/database-extension-disable-mutation.ts +++ b/apps/studio/data/database-extensions/database-extension-disable-mutation.ts @@ -1,7 +1,8 @@ +import pgMeta from '@supabase/pg-meta' import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query' import { toast } from 'sonner' -import { del, handleError } from 'data/fetchers' +import { executeSql } from 'data/sql/execute-sql-query' import type { ResponseError } from 'types' import { databaseExtensionsKeys } from './keys' @@ -9,27 +10,27 @@ export type DatabaseExtensionDisableVariables = { projectRef: string connectionString?: string | null id: string + cascade?: boolean } export async function disableDatabaseExtension({ projectRef, connectionString, id, + cascade, }: DatabaseExtensionDisableVariables) { let headers = new Headers() if (connectionString) headers.set('x-connection-encrypted', connectionString) - const { data, error } = await del('/platform/pg-meta/{ref}/extensions', { - params: { - header: { 'x-connection-encrypted': connectionString! }, - path: { ref: projectRef }, - query: { id }, - }, - headers, + const { sql } = pgMeta.extensions.remove(id, { cascade }) + const { result } = await executeSql({ + projectRef, + connectionString, + sql, + queryKey: ['extension', 'delete', id], }) - if (error) handleError(error) - return data + return result } type DatabaseExtensionDisableData = Awaited> diff --git a/apps/studio/data/database-extensions/database-extension-enable-mutation.ts b/apps/studio/data/database-extensions/database-extension-enable-mutation.ts index 3dc157c7671..68d74ad972b 100644 --- a/apps/studio/data/database-extensions/database-extension-enable-mutation.ts +++ b/apps/studio/data/database-extensions/database-extension-enable-mutation.ts @@ -1,7 +1,8 @@ +import pgMeta from '@supabase/pg-meta' +import { ident } from '@supabase/pg-meta/src/pg-format' import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query' import { toast } from 'sonner' -import { handleError, post } from 'data/fetchers' import { executeSql } from 'data/sql/execute-sql-query' import type { ResponseError } from 'types' import { databaseExtensionsKeys } from './keys' @@ -28,29 +29,15 @@ export async function enableDatabaseExtension({ let headers = new Headers() if (connectionString) headers.set('x-connection-encrypted', connectionString) - if (createSchema) { - try { - await executeSql({ - projectRef, - connectionString, - sql: `create schema if not exists ${schema}`, - }) - } catch (error) { - throw error - } - } - - const { data, error } = await post('/platform/pg-meta/{ref}/extensions', { - params: { - header: { 'x-connection-encrypted': connectionString! }, - path: { ref: projectRef }, - }, - body: { schema, name, version, cascade }, - headers, + const { sql } = pgMeta.extensions.create({ schema, name, version, cascade }) + const { result } = await executeSql({ + projectRef, + connectionString, + sql: createSchema ? `create schema if not exists ${ident(schema)}; ${sql}` : sql, + queryKey: ['extension', 'create'], }) - if (error) handleError(error) - return data + return result } type DatabaseExtensionEnableData = Awaited> diff --git a/packages/pg-meta/src/pg-meta-extensions.ts b/packages/pg-meta/src/pg-meta-extensions.ts index fa5e5e7c861..d3482019068 100644 --- a/packages/pg-meta/src/pg-meta-extensions.ts +++ b/packages/pg-meta/src/pg-meta-extensions.ts @@ -1,4 +1,4 @@ -import { literal } from './pg-format' +import { ident, literal } from './pg-format' import { EXTENSIONS_SQL } from './sql/extensions' import { z } from 'zod' @@ -60,26 +60,10 @@ function create({ name, schema, version, cascade = false }: ExtensionCreateParam sql: string } { const sql = ` -do $$ -begin - -- Check if extension exists - if exists ( - select 1 from pg_extension where extname = ${literal(name)} - ) then - raise exception 'Extension % already exists', ${literal(name)}; - end if; - - execute(format('CREATE EXTENSION %I - %s - %s - %s', - ${literal(name)}, - ${schema ? `'SCHEMA ' || quote_ident(${literal(schema)})` : `''`}, - ${version ? `'VERSION ' || quote_ident(${literal(version)})` : `''`}, - ${cascade ? `'CASCADE'` : `''`} -)); -end -$$;` +CREATE EXTENSION ${ident(name)} + ${schema === undefined ? '' : `SCHEMA ${ident(schema)}`} + ${version === undefined ? '' : `VERSION ${literal(version)}`} + ${cascade ? 'CASCADE' : ''};` return { sql } } @@ -93,36 +77,16 @@ function update( name: string, { update = false, version, schema }: ExtensionUpdateParams ): { sql: string } { - const sql = ` -do $$ -declare - ext record; -begin - -- Check if extension exists - select * into ext from pg_extension where extname = ${literal(name)}; - if ext is null then - raise exception 'Extension % does not exist', ${literal(name)}; - end if; - - ${ - update - ? `execute(format('ALTER EXTENSION %I UPDATE %s', - ${literal(name)}, - ${version ? `'TO ' || quote_ident(${literal(version)})` : `''`} - ));` - : '' + let updateSql = '' + if (update) { + updateSql = `ALTER EXTENSION ${ident(name)} UPDATE ${ + version === undefined ? '' : `TO ${literal(version)}` + };` } + const schemaSql = + schema === undefined ? '' : `ALTER EXTENSION ${ident(name)} SET SCHEMA ${ident(schema)};` - ${ - schema - ? `execute(format('ALTER EXTENSION %I SET SCHEMA %I', - ${literal(name)}, - ${literal(schema)} - ));` - : '' - } -end -$$;` + const sql = `BEGIN; ${updateSql} ${schemaSql} COMMIT;` return { sql } } @@ -131,17 +95,7 @@ type ExtensionRemoveParams = { } function remove(name: string, { cascade = false }: ExtensionRemoveParams = {}): { sql: string } { - const sql = ` -do $$ -declare - ext record; -begin - execute(format('DROP EXTENSION %I %s', - ${literal(name)}, - ${cascade ? `'CASCADE'` : `'RESTRICT'`} - )); -end -$$;` + const sql = `DROP EXTENSION ${ident(name)} ${cascade ? 'CASCADE' : 'RESTRICT'};` return { sql } }