Skip to content

Commit

Permalink
Rework to help (\?) meta command
Browse files Browse the repository at this point in the history
  • Loading branch information
kenshaw committed Nov 10, 2024
1 parent 8d0370a commit a653226
Show file tree
Hide file tree
Showing 6 changed files with 782 additions and 709 deletions.
198 changes: 109 additions & 89 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -699,104 +699,124 @@ Type "help" for help.
(not connected)=> \?
General
\q quit usql
\copyright show usql usage and distribution terms
\drivers display information about available database drivers
\q quit usql
\quit alias for \q
\copyright show usage and distribution terms for usql
\drivers show database drivers available to usql
Query Execute
\g [(OPTIONS)] [FILE] or ; execute query (and send results to file or |pipe)
\go [(OPTIONS)] [FILE] alias for \g
\G [(OPTIONS)] [FILE] as \g, but forces vertical output mode
\ego [(OPTIONS)] [FILE] alias for \G
\gx [(OPTIONS)] [FILE] as \g, but forces expanded output mode
\gexec execute query and execute each value of the result
\gset [PREFIX] execute query and store results in usql variables
\crosstabview [(OPTIONS)] [COLUMNS] execute query and display results in crosstab
\chart CHART [(OPTIONS)] execute query and display results as a chart
\watch [(OPTIONS)] [DURATION] execute query every specified interval
\bind [PARAM]... set query parameters
Help
\? [commands] show help on usql's meta (backslash) commands
\? options show help on usql command-line options
\? variables show help on special usql variables

Query Buffer
\e [FILE] [LINE] edit the query buffer (or file) with external editor
\edit [-exec] edit the query (or exec) buffer
\p show the contents of the query buffer
\raw show the raw (non-interpolated) contents of the query buffer
\exec show the contents of the exec buffer
\r reset (clear) the query buffer
\w FILE write query buffer to file
Connection
\c DSN or \c NAME connect to dsn or named database connection
\c DRIVER PARAMS... connect to database with driver and parameters
\connect alias for \c
\Z close (disconnect) database connection
\disconnect alias for \Z
\password [USER] change password for user
\passwd alias for \password
\conninfo display information about the current database connection

Help
\? [commands] show help on backslash commands
\? options show help on usql command-line options
\? variables show help on special usql variables
Query Execute
\g [(OPTIONS)] [FILE] or ; execute query (and send results to file or |pipe)
\go alias for \g
\G [(OPTIONS)] [FILE] as \g, but forces vertical output mode
\ego alias for \G
\gx [(OPTIONS)] [FILE] as \g, but forces expanded output mode
\gexec execute query and execute each value of the result
\gset [PREFIX] execute query and store results in usql variables
\bind [PARAM]... set query parameters
\timing [on|off] toggle timing of commands

Query View
\crosstab [(OPTIONS)] [COLUMNS] execute query and display results in crosstab
\crosstabview alias for \crosstab
\xtab alias for \crosstab
\chart CHART [(OPTIONS)] execute query and display results as a chart
\watch [(OPTIONS)] [INTERVAL] execute query every specified interval

Input/Output
\copy SRC DST QUERY TABLE copy query from source url to table on destination url
\copy SRC DST QUERY TABLE(A,...) copy query from source url to columns of table on destination url
\echo [-n] [STRING] write string to standard output (-n for no newline)
\qecho [-n] [STRING] write string to \o output stream (-n for no newline)
\warn [-n] [STRING] write string to standard error (-n for no newline)
\o [FILE] send all query results to file or |pipe
\i FILE execute commands from file
\ir FILE as \i, but relative to location of current script
Conditional
\if EXPR begin conditional block
\elif EXPR alternative within current conditional block
\else final alternative within current conditional block
\endif end conditional block
Query Buffer
\e [-raw|-exec] [FILE] [LINE] edit the query buffer, raw (non-interpolated) buffer, the
exec buffer, or a file with external editor
\edit alias for \e
\p [-raw|-exec] show the contents of the query buffer, the raw
(non-interpolated) buffer or the exec buffer
\print alias for \p
\raw alias for \p
\exec alias for \p
\w [-raw|-exec] FILE write the contents of the query buffer, raw
(non-interpolated) buffer, or exec buffer to file
\write alias for \w
\r reset (clear) the query buffer
\reset alias for \r

Informational
\d[S+] [NAME] list tables, views, and sequences or describe table, view, sequence, or index
\da[S+] [PATTERN] list aggregates
\df[S+] [PATTERN] list functions
\di[S+] [PATTERN] list indexes
\dm[S+] [PATTERN] list materialized views
\dn[S+] [PATTERN] list schemas
\dp[S] [PATTERN] list table, view, and sequence access privileges
\ds[S+] [PATTERN] list sequences
\dt[S+] [PATTERN] list tables
\dv[S+] [PATTERN] list views
\l[+] list databases
\ss[+] [TABLE|QUERY] [k] show stats for a table or a query
Formatting
\pset [NAME [VALUE]] set table output option
\a toggle between unaligned and aligned output mode
\C [STRING] set table title, or unset if none
\f [STRING] show or set field separator for unaligned query output
\H toggle HTML output mode
\T [STRING] set HTML <table> tag attributes, or unset if none
\t [on|off] show only rows
\x [on|off|auto] toggle expanded output
\d[S+] [NAME] list tables, views, and sequences or describe table, view,
sequence, or index
\da[S+] [PATTERN] list aggregates
\df[S+] [PATTERN] list functions
\di[S+] [PATTERN] list indexes
\dm[S+] [PATTERN] list materialized views
\dn[S+] [PATTERN] list schemas
\dp[S] [PATTERN] list table, view, and sequence access privileges
\ds[S+] [PATTERN] list sequences
\dt[S+] [PATTERN] list tables
\dv[S+] [PATTERN] list views
\l[+] list databases
\ss[+] [TABLE|QUERY] [k] show stats for a table or a query

Transaction
\begin begin a transaction
\begin -read-only ISOLATION begin a transaction with isolation level
\commit commit current transaction
\rollback rollback (abort) current transaction
Variables
\set [NAME [VALUE]] set usql application variable, or show all usql application
variables if no parameters
\unset NAME unset (delete) usql application variable
\pset [NAME [VALUE]] set table print formatting option, or show all print
formatting options if no parameters
\a toggle between unaligned and aligned output mode
\C [TITLE] set table title, or unset if none
\f [SEPARATOR] show or set field separator for unaligned query output
\H toggle HTML output mode
\T [ATTRIBUTES] set HTML <table> tag attributes, or unset if none
\t [on|off] show only rows
\x [on|off|auto] toggle expanded output
\cset [NAME [URL]] set named connection, or show all named connections if no
parameters
\cset NAME DRIVER PARAMS... set named connection for driver and parameters
\prompt [-TYPE] VAR [PROMPT] prompt user to set application variable

Connection
\c DSN connect to database url
\c DRIVER PARAMS... connect to database with driver and parameters
\cset show named connections
\cset NAME DSN set named connection
\cset NAME DRIVER PARAMS... define named connection for database driver
\Z close database connection
\password [USER] change password for user
\conninfo display information about the current database connection
Operating System
\cd [DIR] change the current working directory
\getenv VARNAME ENVVAR fetch environment variable
\setenv NAME [VALUE] set or unset environment variable
\! [COMMAND] execute command in shell or start interactive shell
\timing [on|off] toggle timing of commands
Input/Output
\echo [-n] [MESSAGE]... write message to standard output (-n for no newline)
\qecho [-n] [MESSAGE]... write message to \o output stream (-n for no newline)
\warn [-n] [MESSAGE]... write message to standard error (-n for no newline)
\o [FILE] send all query results to file or |pipe
\out alias for \o
\copy SRC DST QUERY TABLE copy results of query from source database into table on
destination database
\copy SRC DST QUERY TABLE(A,...) copy results of query from source database into table's
columns on destination database
Control/Conditional
\i FILE execute commands from file
\include alias for \i
\ir FILE as \i, but relative to location of current script
\include_relative alias for \ir
\if EXPR begin conditional block
\elif EXPR alternative within current conditional block
\else final alternative within current conditional block
\endif end conditional block
Variables
\prompt [-TYPE] VAR [PROMPT] prompt user to set variable
\set [NAME [VALUE]] set internal variable, or list all if no parameters
\unset NAME unset (delete) internal variable
Transaction
\begin [-read-only [ISOLATION]] begin transaction, with optional isolation level
\commit commit current transaction
\rollback rollback (abort) current transaction
\abort alias for \rollback
Operating System/Environment
\! [COMMAND] execute command in shell or start interactive shell
\cd [DIR] change the current working directory
\getenv VARNAME ENVVAR fetch environment variable
\setenv NAME [VALUE] set or unset environment variable
```
Parameters passed to commands [can be backticked][backticks].
Expand Down
68 changes: 35 additions & 33 deletions env/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (

// Listing writes a formatted listing of the special environment variables to
// w, separated in sections based on variable type.
func Listing(w io.Writer) {
func Listing(w io.Writer) error {
varsWithDesc := make([]string, len(varNames))
for i, v := range varNames {
varsWithDesc[i] = v.String()
Expand Down Expand Up @@ -48,46 +48,17 @@ func Listing(w io.Writer) {
if configExtra != "" {
configExtra = " (" + configExtra + ")"
}

template := `List of specially treated variables
%s variables:
Usage:
%[1]s --set=NAME=VALUE
or \set NAME VALUE inside %[1]s
%[2]s
Display settings:
Usage:
%[1]s --pset=NAME[=VALUE]
or \pset NAME [VALUE] inside %[1]s
%[3]s
Environment variables:
Usage:
NAME=VALUE [NAME=VALUE] %[1]s ...
or \setenv NAME [VALUE] inside %[1]s
%[4]s
Connection variables:
Usage:
%[1]s --cset NAME[=DSN]
or \cset NAME [DSN] inside %[1]s
or \cset NAME DRIVER PARAMS... inside %[1]s
or define in %[5]s%[6]s
`
fmt.Fprintf(
w, template,
w,
variableTpl,
text.CommandName,
strings.TrimRightFunc(strings.Join(varsWithDesc, ""), unicode.IsSpace),
strings.TrimRightFunc(strings.Join(pvarsWithDesc, ""), unicode.IsSpace),
strings.TrimRightFunc(strings.Join(envVarsWithDesc, ""), unicode.IsSpace),
configDir,
configExtra,
)
return nil
}

func buildConfigDir(configName string) (string, string) {
Expand Down Expand Up @@ -295,3 +266,34 @@ var envVarNames = []varName{
`shell used by the \! command`,
},
}

const variableTpl = `List of specially treated variables
%s variables:
Usage:
%[1]s --set=NAME=VALUE
or \set NAME VALUE inside %[1]s
%[2]s
Display settings:
Usage:
%[1]s --pset=NAME[=VALUE]
or \pset NAME [VALUE] inside %[1]s
%[3]s
Environment variables:
Usage:
NAME=VALUE [NAME=VALUE] %[1]s ...
or \setenv NAME [VALUE] inside %[1]s
%[4]s
Connection variables:
Usage:
%[1]s --cset NAME[=DSN]
or \cset NAME [DSN] inside %[1]s
or \cset NAME DRIVER PARAMS... inside %[1]s
or define in %[5]s%[6]s
`
51 changes: 25 additions & 26 deletions gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,42 +365,42 @@ func parseDriverInfo(tag, filename string) (DriverInfo, error) {

// desc is a meta command description.
type desc struct {
Name string
Params string
Desc string
Func string
Hidden bool
Alias string
Func string
Name string
Params string
Desc string
Hidden bool
Deprecated bool
}

func newDesc(funcName, alias string, v []string) desc {
name, params, descstr := v[0], "", ""
switch len(v) {
case 1:
name, params, descstr, hidden := v[0], "", "", false
switch n := len(v); {
case n == 1:
if i := strings.Index(name, ":"); i != -1 {
name, alias = name[:i], name[i+1:]
}
case 2:
case n == 2:
descstr = v[1]
case 3:
case n >= 3:
params, descstr = v[1], v[2]
}
if descstr == "" {
hidden, descstr = true, `alias for \`+alias
}
return desc{
Name: name,
Params: params,
Desc: descstr,
Func: funcName,
Alias: alias,
Func: funcName,
Name: name,
Params: params,
Desc: descstr,
Hidden: hidden,
Deprecated: v[len(v)-1] == "DEPRECATED",
}
}

func (d desc) String() string {
if d.Desc != "" {
s := strings.ReplaceAll(fmt.Sprintf("%q", d.Desc), "{{CommandName}}", `" + text.CommandName + "`)
return fmt.Sprintf("{%q, %q, %s, %s, %t}", d.Name, d.Params, s, d.Func, false)
}
s := `alias for \` + d.Alias
return fmt.Sprintf("{%q, %q, %q, %s, %t}", d.Name, d.Params, s, d.Func, true)
s := strings.ReplaceAll(d.Desc, "{{CommandName}}", "` + text.CommandName + `")
return fmt.Sprintf("{%s, `%s`, `%s`, `%s`, %t, %t}", d.Func, d.Name, d.Params, s, d.Hidden, d.Deprecated)
}

func findCommand(name string) string {
Expand Down Expand Up @@ -647,17 +647,16 @@ var baseOrder = map[string]int{
var sections = []string{
"General",
"Help",
"Connection",
"Query Execute",
//"Query View",
"Query View",
"Query Buffer",
"Informational",
"Variables",
"Connection",
"Conditional",
"Input/Output",
"Control/Conditional",
"Transaction",
"Operating System/Environment",
//"Formatting",
}

// regexps.
Expand Down
Loading

0 comments on commit a653226

Please sign in to comment.