import { useRouter } from 'next/router' import { useEffect, useRef, useState } from 'react' import { useParams, useTelemetryProps } from 'common' import { getAddons } from 'components/interfaces/Billing/Subscription/Subscription.utils' import AlertError from 'components/ui/AlertError' import DatabaseSelector from 'components/ui/DatabaseSelector' import Panel from 'components/ui/Panel' import ShimmeringLoader from 'components/ui/ShimmeringLoader' import { usePoolingConfigurationQuery } from 'data/database/pooling-configuration-query' import { useReadReplicasQuery } from 'data/read-replicas/replicas-query' import { useProjectAddonsQuery } from 'data/subscriptions/project-addons-query' import { pluckObjectFields } from 'lib/helpers' import Telemetry from 'lib/telemetry' import { useDatabaseSelectorStateSnapshot } from 'state/database-selector' import { useDatabaseSettingsStateSnapshot } from 'state/database-settings' import { AlertDescription_Shadcn_, AlertTitle_Shadcn_, Alert_Shadcn_, Input } from 'ui' import { WarningIcon } from 'ui' import { DefaultSessionModeNotice, IPv4AddonDirectConnectionNotice, IPv4DeprecationNotice, } from '../DatabaseConnectionNotices' import { UsePoolerCheckbox } from '../UsePoolerCheckbox' import ResetDbPassword from './ResetDbPassword' const DatabaseSettings = () => { const router = useRouter() const { ref: projectRef, connectionString } = useParams() const telemetryProps = useTelemetryProps() const snap = useDatabaseSettingsStateSnapshot() const state = useDatabaseSelectorStateSnapshot() const connectionStringsRef = useRef(null) const [poolingMode, setPoolingMode] = useState<'transaction' | 'session'>('transaction') const { data: poolingInfo, error: poolingInfoError, isLoading: isLoadingPoolingInfo, isError: isErrorPoolingInfo, isSuccess: isSuccessPoolingInfo, } = usePoolingConfigurationQuery({ projectRef, }) const { data: databases, error: readReplicasError, isLoading: isLoadingReadReplicas, isError: isErrorReadReplicas, isSuccess: isSuccessReadReplicas, } = useReadReplicasQuery({ projectRef }) const { data: addons, error: addOnsError, isLoading: isLoadingAddons, isError: isErrorAddons, isSuccess: isSuccessAddons, } = useProjectAddonsQuery({ projectRef }) const error = readReplicasError || poolingInfoError || addOnsError const isLoading = isLoadingReadReplicas || isLoadingPoolingInfo || isLoadingAddons const isError = isErrorReadReplicas || isErrorPoolingInfo || isErrorAddons const isSuccess = isSuccessReadReplicas && isSuccessPoolingInfo && isSuccessAddons const selectedDatabase = (databases ?? []).find( (db) => db.identifier === state.selectedDatabaseId ) const primaryConfig = poolingInfo?.find((x) => x.identifier === state.selectedDatabaseId) const defaultPoolingMode = primaryConfig?.pool_mode const { ipv4: ipv4Addon } = getAddons(addons?.selected_addons ?? []) const isMd5 = primaryConfig?.connectionString.includes('?options=reference') const DB_FIELDS = ['db_host', 'db_name', 'db_port', 'db_user'] const emptyState = { db_user: '', db_host: '', db_port: '', db_name: '' } const dbConnectionInfo = pluckObjectFields(selectedDatabase || emptyState, DB_FIELDS) const connectionInfo = snap.usePoolerConnection ? { db_host: primaryConfig?.db_host, db_name: primaryConfig?.db_name, db_port: primaryConfig?.db_port, db_user: primaryConfig?.db_user, } : dbConnectionInfo const handleCopy = (labelValue?: string) => Telemetry.sendEvent( { category: 'settings', action: 'copy_connection_string', label: labelValue ? labelValue : '', }, telemetryProps, router ) useEffect(() => { if (connectionString !== undefined && connectionStringsRef.current !== undefined) { state.setSelectedDatabaseId(connectionString) connectionStringsRef.current?.scrollIntoView({ block: 'center', behavior: 'smooth' }) } }, [connectionString]) useEffect(() => { if (primaryConfig?.pool_mode === 'session') { setPoolingMode(primaryConfig.pool_mode) } }, [primaryConfig?.pool_mode]) return ( <>
Connection parameters
} > {isLoading && Array.from({ length: 5 }).map((_, i) => (
))} {isError && } {isSuccess && ( <>
{defaultPoolingMode === 'session' && poolingMode === 'transaction' && ( )} {ipv4Addon !== undefined && poolingMode === 'session' && snap.usePoolerConnection && } {ipv4Addon === undefined && !snap.usePoolerConnection && ( )} {isMd5 && ( If you are connecting to your database via a GUI client, use the{' '} connection string above instead GUI clients only support database connections for Postgres 13 via a connection string. )}
{ handleCopy('Host') }} /> {isMd5 && snap.usePoolerConnection && ( )} )}
) } export default DatabaseSettings