xo / usql

Universal command-line interface for SQL databases
MIT License
8.91k stars 351 forks source link

[PATCH] A handy conninfo output #434

Closed mapperr closed 10 months ago

mapperr commented 10 months ago

Hi!

thank you for usql, is awesome : )

I was wandering how to change database when connected to a postgres server, and I get that with psql we do a \c <database_name>.

usql expects the whole db url, and I did not see a command to do the same as psql with just the db name, so I was thinking that maybe just changing the output of conninfo can be handy to copy paste and change the db without exiting usql.

Here a patch:

From 65d8e6c334340c56601397259017717c02caa2c5 Mon Sep 17 00:00:00 2001
From: mapperr <mapperr@sdf.ee>
Date: Wed, 29 Nov 2023 18:34:37 +0100
Subject: [PATCH] A handy conninfo output

---
 text/text.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/text/text.go b/text/text.go
index c60eae3..5831914 100644
--- a/text/text.go
+++ b/text/text.go
@@ -26,7 +26,7 @@ var (
    Copyright             = CommandName + ", " + Banner + ".\n\n" + License
    RowCount              = `(%d rows)`
    AvailableDrivers      = `Available Drivers:`
-   ConnInfo              = `Connected with driver %s (%s)`
+   ConnInfo              = `Connected with \c %s %s`
    EnterPassword         = `Enter password: `
    EnterPreviousPassword = `Enter previous password: `
    PasswordsDoNotMatch   = `Passwords do not match, trying again ...`
-- 
2.43.0

so we can:

\conninfo
Connected with \c postgres dbname=postgres host=myhost.com password=mypass port=5432 user=postgres

and copy paste the
\c postgres dbname=postgres host=myhost.com password=mypass port=5432 user=postgres bit as
\c postgres dbname=mydb host=myhost.com password=mypass port=5432 user=postgres

Makes sense to you?

kenshaw commented 10 months ago

We purposefully do not display the full connection string during the connection, as usql is likely to be used in automated scripts where the password (or other sensitive connection details) would be captured by logging. If you need the full connection string after-the-fact, there is the \conninfo command:

$ usql
Type "help" for help.

(not connected)=> \c postgres://postgres:P4ssw0rd@localhost/
Connected with driver postgres (PostgreSQL 16.0 (Debian 16.0-1.pgdg120+1))
pg:postgres@localhost=> \conninfo
Connected with driver postgres (host=localhost password=P4ssw0rd user=postgres)
pg:postgres@localhost=>  
kenshaw commented 10 months ago

To answer your other inquiry, there are two forms of the \connect (alias \c) ccommand:

Connection
  \c DSN                               connect to database url
  \c DRIVER PARAMS...                  connect to database with driver and parameters
  \Z                                   close database connection
  \password [USERNAME]                 change the password for a user
  \conninfo                            display information about the current database connection

Specifically, you can bypass usql's internal connection URL parsing (dburl) and just pass whatever DSN connection you want:

(not connected)=> \c postgres user=postgres password=P4ssw0rd host=localhost
Connected with driver postgres (PostgreSQL 16.0 (Debian 16.0-1.pgdg120+1))
pg:=> \conninfo
Connected with driver postgres (user=postgres password=P4ssw0rd host=localhost)
pg:=>  

You will need to research each underlying database drivers to figure out what the actual DSN would look like, as its different for each. For example, here's what a connection to MySQL looks like:

my:root@localhost=> \c my://root:P4ssw0rd@localhost
Connected with driver mysql (11.1.2-MariaDB-1:11.1.2+maria~ubu2204)
my:root@localhost=> \conninfo
Connected with driver mysql (root:P4ssw0rd@tcp(localhost:3306)/?loc=Local&parseTime=true&sql_mode=ansi)

Note however, that usql mutates some database connection strings when using the URL form, in order to add the proper connection settings necessary to make the driver behave/be more compatible with usql, such as the parseTime, and sql_mode parameters injected to the MySQL DSN. Note also that this is not an actual standard URL. You could copy/paste this and then connect with different parameters directly:

my:root@localhost=> \c mysql root:P4ssw0rd@tcp(localhost:3306)/
Connected with driver mysql (11.1.2-MariaDB-1:11.1.2+maria~ubu2204)
my:=> \conninfo
Connected with driver mysql (root:P4ssw0rd@tcp(localhost:3306)/)

For the most part, I would recommend using the URL form wherever possible, as it's much easier to read.