import { FC, useState, useEffect } from 'react' import { observer } from 'mobx-react-lite' import { useStore } from 'hooks' import { pluckObjectFields } from 'lib/helpers' import Loading from 'components/ui/Loading' import Panel from 'components/ui/Panel' import Divider from 'components/ui/Divider' import { AutoField } from 'uniforms-bootstrap4' import { API_URL } from 'lib/constants' import { patch } from 'lib/common/fetch' import ToggleField from 'components/to-be-cleaned/forms/ToggleField' import SchemaFormPanel from 'components/to-be-cleaned/forms/SchemaFormPanel' import { Input } from 'ui' interface Props {} const ConnectionPooling: FC = () => { const { ui, app } = useStore() const projectRef = ui.selectedProject?.ref ?? 'default' const [isLoading, setIsLoading] = useState(true) const [poolingConfiguration, setPoolingConfiguration] = useState() useEffect(() => { fetchPoolingConfiguration() }, []) const fetchPoolingConfiguration = async () => { setIsLoading(true) const response = await app.database.getPoolingConfiguration(projectRef) setPoolingConfiguration(response) setIsLoading(false) } if (isLoading) return if (poolingConfiguration.error) { return (

Error loading pooling configuration

) } const { project } = poolingConfiguration // for older projects if (!project.pgbouncer_enabled && project.pool_mode == null) return ( Connection Pooling is not available for this project } >

Please start a new project to enable this feature.

) const formModel = project const DB_FIELDS = ['db_host', 'db_name', 'db_port', 'db_user', 'inserted_at'] const connectionInfo = pluckObjectFields(formModel, DB_FIELDS) const BOUNCER_FIELDS = [ 'default_pool_size', 'ignore_startup_parameters', 'pool_mode', 'pgbouncer_enabled', ] const bouncerInfo = pluckObjectFields(formModel, BOUNCER_FIELDS) return ( ) } export default observer(ConnectionPooling) interface ConfigProps { projectRef: string bouncerInfo: { default_pool_size: number ignore_startup_parameters: 'string' pool_mode: string pgbouncer_enabled: boolean } connectionInfo: { db_host: string db_name: string db_port: number db_user: string inserted_at: string } } export const PgbouncerConfig: FC = observer( ({ projectRef, bouncerInfo, connectionInfo }) => { const { ui } = useStore() const [updates, setUpdates] = useState({ pgbouncer_enabled: bouncerInfo.pgbouncer_enabled, pool_mode: bouncerInfo.pool_mode || 'transaction', default_pool_size: bouncerInfo.default_pool_size || '', ignore_startup_parameters: bouncerInfo.ignore_startup_parameters || '', }) const updateConfig = async (updatedConfig: any) => { try { const response = await patch(`${API_URL}/props/pooling/${projectRef}/config`, updatedConfig) if (response.error) { throw response.error } else { setUpdates({ ...response.project }) ui.setNotification({ category: 'success', message: 'Successfully saved settings' }) } } catch (error: any) { ui.setNotification({ category: 'error', message: `Failed to update config: ${error.message}`, }) } } const formSchema = { properties: { pgbouncer_enabled: { title: 'Enabled', type: 'boolean', help: 'Activates / deactivates Connection Pooling.', }, pool_mode: { title: 'Pool Mode', type: 'string', options: [ { label: 'Transaction', value: 'transaction', }, { label: 'Session', value: 'session', }, { label: 'Statement', value: 'statement', }, ], }, ignore_startup_parameters: { title: 'Ignore Startup Parameters', type: 'string', readOnly: true, help: 'Defaults are either blank or "extra_float_digits"', }, }, required: ['pool_mode'], type: 'object', } return ( setUpdates(model)} onSubmit={(model: any) => updateConfig(model)} onReset={() => setUpdates(bouncerInfo)} >
{updates.pgbouncer_enabled && ( <>

Specify when a connection can be returned to the pool. To find out the most suitable mode for your use case,{' '} click here .

)}
) } )