diff --git a/apps/studio/components/interfaces/Settings/Database/ConnectionPooling/ConnectionPooling.tsx b/apps/studio/components/interfaces/Settings/Database/ConnectionPooling/ConnectionPooling.tsx index afcd5f6aa2..882a1c562d 100644 --- a/apps/studio/components/interfaces/Settings/Database/ConnectionPooling/ConnectionPooling.tsx +++ b/apps/studio/components/interfaces/Settings/Database/ConnectionPooling/ConnectionPooling.tsx @@ -32,6 +32,7 @@ import { usePoolingConfigurationUpdateMutation } from 'data/database/pooling-con import { useProjectAddonsQuery } from 'data/subscriptions/project-addons-query' import { useCheckPermissions, useStore } from 'hooks' import { POOLING_OPTIMIZATIONS } from './ConnectionPooling.constants' +import { constructConnStringSyntax, getPoolerTld } from './ConnectionPooling.utils' const formId = 'connection-pooling-form' @@ -72,8 +73,18 @@ export const ConnectionPooling = () => { isSuccess, } = usePoolingConfigurationQuery({ projectRef: projectRef }) + const poolerTld = isSuccess ? getPoolerTld(poolingInfo.connectionString) : 'com' const connectionPoolingUnavailable = !poolingInfo?.pgbouncer_enabled && poolingInfo?.pool_mode === null + const poolerConnStringSyntax = isSuccess + ? constructConnStringSyntax(poolingInfo?.connectionString, { + ref: projectRef as string, + cloudProvider: project!.cloud_provider, + region: project!.region, + tld: poolerTld, + portNumber: poolingInfo.db_port.toString(), + }) + : [] // [Joshen] TODO this needs to be obtained from BE as 26th Jan is when we'll start - projects will be affected at different rates const resolvesToIpV6 = !poolingInfo?.supavisor_enabled && false // Number(new Date()) > Number(dayjs.utc('01-26-2024', 'MM-DD-YYYY').toDate()) @@ -417,142 +428,39 @@ export const ConnectionPooling = () => { You may also connect to another database or with another user via Supavisor with the following URI format:

-

- postgres:// - - - [db-user] - - - - - -

- - Database user (e.g postgres) - -
- - - - - . - - - {project?.ref} - - - - - -
- - Project's reference ID - -
-
-
-
-
- : - - - [db-password] - - - - - -
- Database password -
-
-
-
-
- @aws-0- - - - {project?.region} - - - - - -
- Project's region -
-
-
-
-
- .pooler.supabase.com: - - - {poolingInfo.db_port} - - - - - -
- - Database port number (Use 5432 if using prepared statements) - -
-
-
-
-
- / - - - [db-name] - - - - - -
- - Database name (e.g postgres) - -
-
-
-
-
-

+ + {poolerConnStringSyntax.length > 0 && ( +

+ {poolerConnStringSyntax.map((x, idx) => { + if (x.tooltip) { + return ( + + + {x.value} + + + + + +

+ {x.tooltip} +
+ + + + + ) + } else { + return x.value + } + })} +

+ )} ) } diff --git a/apps/studio/components/interfaces/Settings/Database/ConnectionPooling/ConnectionPooling.utils.ts b/apps/studio/components/interfaces/Settings/Database/ConnectionPooling/ConnectionPooling.utils.ts new file mode 100644 index 0000000000..4dbc4d494b --- /dev/null +++ b/apps/studio/components/interfaces/Settings/Database/ConnectionPooling/ConnectionPooling.utils.ts @@ -0,0 +1,55 @@ +// [Joshen] This is to the best of interpreting the syntax from the API response +// // There's different format for PG13 (depending on authentication method being md5) and PG14 +export const constructConnStringSyntax = ( + connString: string, + { + ref, + cloudProvider, + region, + tld, + portNumber, + }: { ref: string; cloudProvider: string; region: string; tld: string; portNumber: string } +) => { + if (connString.includes('postgres:[YOUR-PASSWORD]')) { + // PG 13 + Authentication MD5 + return [ + { value: 'postgres://', tooltip: undefined }, + { value: '[user]', tooltip: 'Database user (e.g postgres)' }, + { value: ':', tooltip: undefined }, + { value: '[password]', tooltip: 'Database password' }, + { value: '@', tooltip: undefined }, + { value: cloudProvider.toLocaleLowerCase(), tooltip: 'Cloud provider' }, + { value: '-0-', tooltip: undefined }, + { value: region, tooltip: "Project's region" }, + { value: `.pooler.supabase.${tld}:`, tooltip: undefined }, + { value: portNumber, tooltip: 'Port number (Use 5432 if using prepared statements)' }, + { value: '/', tooltip: undefined }, + { value: '[db-name]', tooltip: 'Database name (e.g postgres)' }, + { value: `?options=reference%3D`, tooltip: undefined }, + { value: ref, tooltip: "Project's reference ID" }, + ] + } else { + return [ + { value: 'postgres://', tooltip: undefined }, + { value: '[user]', tooltip: 'Database user (e.g postgres)' }, + { value: '.', tooltip: undefined }, + { value: ref, tooltip: "Project's reference ID" }, + { value: ':', tooltip: undefined }, + { value: '[password]', tooltip: 'Database password' }, + { value: '@', tooltip: undefined }, + { value: cloudProvider.toLocaleLowerCase(), tooltip: 'Cloud provider' }, + { value: '-0-', tooltip: undefined }, + { value: region, tooltip: "Project's region" }, + { value: `.pooler.supabase.${tld}:`, tooltip: undefined }, + { value: portNumber, tooltip: 'Port number (Use 5432 if using prepared statements)' }, + { value: '/', tooltip: undefined }, + { value: '[db-name]', tooltip: 'Database name (e.g postgres)' }, + ] + } +} + +export const getPoolerTld = (connString: string) => { + const segment = connString.split('pooler.supabase.')[1] + const tld = segment.split(':6543')[0] + return tld +}