2020-08-06 20:58:47 +03:00
|
|
|
package cli
|
|
|
|
|
|
|
|
import (
|
2024-01-15 04:45:34 +03:00
|
|
|
"log/slog"
|
|
|
|
|
2020-08-06 20:58:47 +03:00
|
|
|
"github.com/spf13/cobra"
|
|
|
|
|
2023-11-20 04:06:36 +03:00
|
|
|
"github.com/neilotoole/sq/cli/flag"
|
2024-01-15 04:45:34 +03:00
|
|
|
"github.com/neilotoole/sq/cli/output/format"
|
2023-11-20 04:06:36 +03:00
|
|
|
_ "github.com/neilotoole/sq/drivers" // Load drivers
|
2020-08-06 20:58:47 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
func newRootCmd() *cobra.Command {
|
|
|
|
cmd := &cobra.Command{
|
|
|
|
Use: `sq QUERY`,
|
|
|
|
Short: "sq",
|
2023-03-12 06:25:19 +03:00
|
|
|
Long: `sq is a swiss-army knife for wrangling data.
|
2020-08-06 20:58:47 +03:00
|
|
|
|
2023-06-17 07:54:25 +03:00
|
|
|
$ sq '@sakila_pg | .actor | where(.actor_id > 2) | .first_name, .last_name | .[0:10]'
|
2023-05-25 02:36:10 +03:00
|
|
|
|
2023-04-16 01:28:51 +03:00
|
|
|
Use sq to query Postgres, SQLite, SQLServer, MySQL, CSV, Excel, etc,
|
2023-05-25 02:36:10 +03:00
|
|
|
and output in text, JSON, CSV, Excel and so on, or write output to a
|
|
|
|
database table.
|
2020-08-06 20:58:47 +03:00
|
|
|
|
|
|
|
You can query using sq's own jq-like syntax, or in native SQL.
|
|
|
|
|
2023-04-16 01:28:51 +03:00
|
|
|
Use "sq inspect" to view schema metadata. Use the "sq tbl" commands
|
2024-01-15 04:45:34 +03:00
|
|
|
to copy, truncate and drop tables. Use "sq diff" to compare source
|
|
|
|
metadata and row data.
|
2021-02-22 10:37:00 +03:00
|
|
|
|
2023-04-16 01:28:51 +03:00
|
|
|
See docs and more: https://sq.io`,
|
2023-11-19 03:05:48 +03:00
|
|
|
Example: ` # Add Postgres source.
|
|
|
|
$ sq add postgres://user@localhost/sakila -p
|
|
|
|
Password: ****
|
2020-08-06 20:58:47 +03:00
|
|
|
|
2023-05-25 02:36:10 +03:00
|
|
|
# List available data sources.
|
2021-02-22 10:37:00 +03:00
|
|
|
$ sq ls
|
2020-08-06 20:58:47 +03:00
|
|
|
|
2023-05-25 02:36:10 +03:00
|
|
|
# Set active data source.
|
2021-02-22 10:37:00 +03:00
|
|
|
$ sq src @sakila_pg
|
2020-08-06 20:58:47 +03:00
|
|
|
|
2023-05-25 02:36:10 +03:00
|
|
|
# Get specified cols from table address in active data source.
|
|
|
|
$ sq '.actor | .actor_id, .first_name, .last_name'
|
2020-08-06 20:58:47 +03:00
|
|
|
|
2023-05-25 02:36:10 +03:00
|
|
|
# Ping a data source.
|
|
|
|
$ sq ping @sakila_pg
|
|
|
|
|
|
|
|
# View metadata (schema, stats etc) for data source.
|
2021-02-22 10:37:00 +03:00
|
|
|
$ sq inspect @sakila_pg
|
2020-08-06 20:58:47 +03:00
|
|
|
|
2023-05-25 02:36:10 +03:00
|
|
|
# View metadata for a table.
|
|
|
|
$ sq inspect @sakila_pg.actor
|
|
|
|
|
|
|
|
# Output all rows from 'actor' table in JSON.
|
|
|
|
$ sq -j .actor
|
2020-08-06 20:58:47 +03:00
|
|
|
|
2023-05-25 02:36:10 +03:00
|
|
|
# Output in text format (with header).
|
|
|
|
$ sq -th .actor
|
2020-08-06 20:58:47 +03:00
|
|
|
|
2023-05-25 02:36:10 +03:00
|
|
|
# Output in text format (no header).
|
|
|
|
$ sq -tH .actor
|
2020-08-06 20:58:47 +03:00
|
|
|
|
2023-05-25 02:36:10 +03:00
|
|
|
# Output to a HTML file.
|
|
|
|
$ sq --html '@sakila_pg.actor' -o actor.html
|
2020-08-06 20:58:47 +03:00
|
|
|
|
2023-05-25 02:36:10 +03:00
|
|
|
# Join across data sources.
|
2021-02-22 10:37:00 +03:00
|
|
|
$ sq '@my1.person, @pg1.address | join(.uid) | .username, .email, .city'
|
2020-08-06 20:58:47 +03:00
|
|
|
|
2023-05-25 02:36:10 +03:00
|
|
|
# Insert query results into a table in another data source.
|
2021-02-22 10:37:00 +03:00
|
|
|
$ sq --insert=@pg1.person '@my1.person | .username, .email'
|
2020-08-06 20:58:47 +03:00
|
|
|
|
2023-05-25 02:36:10 +03:00
|
|
|
# Execute a database-native SQL query, specifying the source.
|
2021-02-22 10:37:00 +03:00
|
|
|
$ sq sql --src=@pg1 'SELECT uid, username, email FROM person LIMIT 2'
|
2020-08-06 20:58:47 +03:00
|
|
|
|
2023-05-25 02:36:10 +03:00
|
|
|
# Copy a table (in the same source).
|
|
|
|
$ sq tbl copy @sakila_pg.actor .actor2
|
|
|
|
|
|
|
|
# Truncate table.
|
|
|
|
$ sq tbl truncate @sakila_pg.actor2
|
2020-08-06 20:58:47 +03:00
|
|
|
|
2023-05-25 02:36:10 +03:00
|
|
|
# Drop table.
|
|
|
|
$ sq tbl drop @sakila_pg.actor2
|
2020-08-06 20:58:47 +03:00
|
|
|
|
2023-05-25 02:36:10 +03:00
|
|
|
# Pipe an Excel file and output the first 10 rows from sheet1
|
|
|
|
$ cat data.xlsx | sq '.sheet1 | .[0:10]'`,
|
2020-08-06 20:58:47 +03:00
|
|
|
}
|
|
|
|
|
2023-05-22 18:08:14 +03:00
|
|
|
cmd.Flags().SortFlags = false
|
|
|
|
cmd.PersistentFlags().SortFlags = false
|
2024-02-01 02:09:59 +03:00
|
|
|
cmd.CompletionOptions.DisableDescriptions = true
|
2023-05-22 18:08:14 +03:00
|
|
|
|
2023-05-03 15:36:10 +03:00
|
|
|
// The --help flag must be explicitly added to rootCmd,
|
|
|
|
// or else cobra tries to do its own (unwanted) thing.
|
|
|
|
// The behavior of cobra in this regard seems to have
|
|
|
|
// changed? This particular incantation currently does the trick.
|
|
|
|
cmd.PersistentFlags().Bool(flag.Help, false, "Show help")
|
|
|
|
|
2020-08-06 20:58:47 +03:00
|
|
|
addQueryCmdFlags(cmd)
|
2023-05-03 15:36:10 +03:00
|
|
|
|
2024-02-09 21:54:37 +03:00
|
|
|
cmd.Flags().Bool(flag.Version, false, flag.VersionUsage)
|
2024-01-15 04:45:34 +03:00
|
|
|
|
2024-02-09 21:54:37 +03:00
|
|
|
addOptionFlag(cmd.PersistentFlags(), OptMonochrome)
|
2024-01-15 04:45:34 +03:00
|
|
|
addOptionFlag(cmd.PersistentFlags(), OptProgress)
|
2024-02-09 20:25:58 +03:00
|
|
|
addOptionFlag(cmd.PersistentFlags(), OptRedact)
|
2024-02-09 21:54:37 +03:00
|
|
|
addOptionFlag(cmd.PersistentFlags(), OptVerbose)
|
2024-02-09 20:25:58 +03:00
|
|
|
|
2024-02-09 21:54:37 +03:00
|
|
|
// flag.Config can't use the option flag mechanism, because... well,
|
|
|
|
// because it's the config flag, and it exists above the realm of
|
|
|
|
// options. It's the flag that tells us where to find the config file,
|
|
|
|
// thus it can't be an option stored in the config file.
|
2023-04-19 08:28:09 +03:00
|
|
|
cmd.PersistentFlags().String(flag.Config, "", flag.ConfigUsage)
|
2023-05-22 18:08:14 +03:00
|
|
|
|
2024-02-09 21:54:37 +03:00
|
|
|
addOptionFlag(cmd.PersistentFlags(), OptLogEnabled)
|
|
|
|
panicOn(cmd.RegisterFlagCompletionFunc(OptLogEnabled.Flag(), completeBool))
|
2024-01-15 04:45:34 +03:00
|
|
|
|
2024-02-09 21:54:37 +03:00
|
|
|
addOptionFlag(cmd.PersistentFlags(), OptLogFile)
|
|
|
|
|
|
|
|
addOptionFlag(cmd.PersistentFlags(), OptLogLevel)
|
|
|
|
panicOn(cmd.RegisterFlagCompletionFunc(OptLogLevel.Flag(), completeStrings(
|
2024-01-15 04:45:34 +03:00
|
|
|
1,
|
|
|
|
slog.LevelDebug.String(),
|
|
|
|
slog.LevelInfo.String(),
|
|
|
|
slog.LevelWarn.String(),
|
|
|
|
slog.LevelError.String(),
|
|
|
|
)))
|
|
|
|
|
2024-02-09 21:54:37 +03:00
|
|
|
addOptionFlag(cmd.PersistentFlags(), OptLogFormat)
|
|
|
|
panicOn(cmd.RegisterFlagCompletionFunc(OptLogFormat.Flag(), completeStrings(
|
2024-01-15 04:45:34 +03:00
|
|
|
1,
|
|
|
|
string(format.Text),
|
|
|
|
string(format.JSON),
|
|
|
|
)))
|
2024-02-09 21:54:37 +03:00
|
|
|
|
2020-08-06 20:58:47 +03:00
|
|
|
return cmd
|
|
|
|
}
|