mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
fix: move extension requests to query route (#35583)
* fix: move extension requests to query route * chore: escape schema name as identifier
This commit is contained in:
1 parent
e2fddfeeeb
commit
ca06acef00
3 files changed
+34
-92
No files matched your search
@@ -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<ReturnType<typeof disableDatabaseExtension>>
|
||||
|
||||
@@ -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<ReturnType<typeof enableDatabaseExtension>>
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user