@@ -474,15 +474,37 @@ protected function testDatabaseConnection(array $config): bool
474474 return false ;
475475 }
476476 $ this ->createConnection ($ config );
477+ } elseif ($ type === 'pgsql ' ) {
478+ // PostgreSQL requires a database name; otherwise it defaults to using the username.
479+ // To support environments where `postgres` is missing/restricted, accept either:
480+ // - successful connect to a maintenance DB (postgres/template1), or
481+ // - successful connect to the target DB (if only that one is accessible).
482+ $ maintenanceOk = false ;
483+ $ maintenanceErr = null ;
484+
485+ $ configForOps = $ config ;
486+ unset($ configForOps ['name ' ]);
487+ $ dbh = $ this ->createPostgresMaintenanceConnection ($ configForOps , $ maintenanceErr );
488+ $ maintenanceOk = $ dbh !== null ;
489+
490+ $ targetOk = false ;
491+ $ targetErr = null ;
492+ if (!empty ($ config ['name ' ])) {
493+ try {
494+ $ this ->createConnection ($ config , true );
495+ $ targetOk = true ;
496+ } catch (PDOException $ e ) {
497+ $ targetErr = $ e ;
498+ }
499+ }
500+
501+ if (!$ maintenanceOk && !$ targetOk ) {
502+ throw $ targetErr ?? $ maintenanceErr ?? new PDOException ('PostgreSQL connection failed. ' );
503+ }
477504 } else {
478505 // For server-based databases, try to connect without database name first
479506 $ configWithoutDb = $ config ;
480507 unset($ configWithoutDb ['name ' ]);
481- if ($ type === 'pgsql ' ) {
482- // PostgreSQL requires a database name; otherwise it defaults to using the username.
483- // Use a maintenance database for credential/host validation.
484- $ configWithoutDb ['name ' ] = 'postgres ' ;
485- }
486508 $ this ->createConnection ($ configWithoutDb );
487509
488510 // If database name is provided, try to connect to it
@@ -528,6 +550,7 @@ protected function askRetryDatabaseConnection(): bool
528550 {
529551 $ options = ['Exit installation ' , 'Try again ' ];
530552 $ active = 0 ;
553+ $ buffer = '' ;
531554
532555 // Display question in cyan without icon
533556 $ this ->tui ->addLog ('Would you like to try again or exit installation? ' , 'ask ' );
@@ -540,31 +563,42 @@ protected function askRetryDatabaseConnection(): bool
540563 $ this ->setSttyMode ('-icanon -echo ' );
541564 try {
542565 while (true ) {
543- $ key = fread (STDIN , 3 );
544- if ($ key === '' || $ key === false ) {
566+ $ chunk = fread (STDIN , 3 );
567+ if ($ chunk === '' || $ chunk === false ) {
545568 usleep (20000 );
546569 continue ;
547570 }
548571
549- switch ($ key ) {
572+ $ buffer .= $ chunk ;
573+ if (strlen ($ buffer ) > 3 ) {
574+ $ buffer = substr ($ buffer , -3 );
575+ }
576+
577+ $ prevActive = $ active ;
578+ switch ($ buffer ) {
550579 case "\033[D " : // ←
551580 case "\033[A " : // ↑
552581 $ active = max (0 , $ active - 1 );
582+ $ buffer = '' ;
553583 break ;
554584
555585 case "\033[C " : // →
556586 case "\033[B " : // ↓
557587 $ active = min (count ($ options ) - 1 , $ active + 1 );
588+ $ buffer = '' ;
558589 break ;
559590
560591 case "\n" : // Enter
592+ case "\r" : // Enter (some terminals)
561593 $ active
562594 ? $ this ->tui ->replaceLastLogs ('Reinput DB connections. ' , 2 )
563595 : $ this ->tui ->replaceLastLogs ('Exit ... ' , 3 );
564596 return $ active ;
565597 }
566598
567- $ this ->tui ->replaceLastLog ($ this ->tui ->renderRadio ($ options , $ active ));
599+ if ($ active !== $ prevActive ) {
600+ $ this ->tui ->replaceLastLog ($ this ->tui ->renderRadio ($ options , $ active ));
601+ }
568602 }
569603 } finally {
570604 $ this ->setSttyMode ('sane ' );
0 commit comments