diff --git a/cmd/kwil-cli/cmds/call-action.go b/cmd/kwil-cli/cmds/call-action.go index d364198e1a..6253dcccc5 100644 --- a/cmd/kwil-cli/cmds/call-action.go +++ b/cmd/kwil-cli/cmds/call-action.go @@ -150,12 +150,25 @@ func (r *respCall) MarshalJSON() ([]byte, error) { return bts, nil } +func getStringRows(v [][]any) [][]string { + var rows [][]string + for _, r := range v { + var row []string + for _, c := range r { + row = append(row, fmt.Sprintf("%v", c)) + } + rows = append(rows, row) + } + + return rows +} + func (r *respCall) MarshalText() (text []byte, err error) { if !r.PrintLogs { - return recordsToTable(r.Data.QueryResult.ExportToStringMap(), r.tableConf), nil + return recordsToTable(r.Data.QueryResult.ColumnNames, getStringRows(r.Data.QueryResult.Values), r.tableConf), nil } - bts := recordsToTable(r.Data.QueryResult.ExportToStringMap(), r.tableConf) + bts := recordsToTable(r.Data.QueryResult.ColumnNames, getStringRows(r.Data.QueryResult.Values), r.tableConf) if len(r.Data.Logs) > 0 { bts = append(bts, []byte("\n\nLogs:")...) diff --git a/cmd/kwil-cli/cmds/exec-sql.go b/cmd/kwil-cli/cmds/exec-sql.go index 3d60fab8bf..a7c3746094 100644 --- a/cmd/kwil-cli/cmds/exec-sql.go +++ b/cmd/kwil-cli/cmds/exec-sql.go @@ -104,7 +104,7 @@ func execSQLCmd() *cobra.Command { }, } - cmd.Flags().StringVarP(&sqlStmt, "statement", "s", "", "the SQL statement to execute") + cmd.Flags().StringVarP(&sqlStmt, "stmt", "s", "", "the SQL statement to execute") cmd.Flags().StringVarP(&sqlFilepath, "file", "f", "", "the file containing the SQL statement(s) to execute") cmd.Flags().StringArrayVarP(¶ms, "param", "p", nil, `the parameters to pass to the SQL statement. format: "key:type=value"`) common.BindTxFlags(cmd) diff --git a/cmd/kwil-cli/cmds/query.go b/cmd/kwil-cli/cmds/query.go index 25a25ad4b4..239ccff1b2 100644 --- a/cmd/kwil-cli/cmds/query.go +++ b/cmd/kwil-cli/cmds/query.go @@ -34,15 +34,27 @@ kwil-cli query "SELECT * FROM my_table WHERE id = $id" --param id:int=1` func queryCmd() *cobra.Command { var namedParams []string var gwAuth, rpcAuth bool + var stmt string cmd := &cobra.Command{ Use: "query", Short: "Execute a SELECT statement against the database", Long: queryLong, Example: queryExample, + Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - if len(args) != 1 { - return display.PrintErr(cmd, fmt.Errorf("SELECT statement must be the only argument")) + var sqlStmt string + switch { + case stmt != "" && len(args) == 0: + sqlStmt = stmt + case stmt == "" && len(args) == 1: + sqlStmt = args[0] + case stmt != "" && len(args) == 1: + return display.PrintErr(cmd, fmt.Errorf("cannot provide both a --stmt flag and an argument")) + case stmt == "" && len(args) == 0: + return display.PrintErr(cmd, fmt.Errorf("no SQL statement provided")) + default: + return display.PrintErr(cmd, fmt.Errorf("unexpected error")) } tblConf, err := getTableConfig(cmd) @@ -69,13 +81,13 @@ func queryCmd() *cobra.Command { return display.PrintErr(cmd, err) } - _, err = parse.Parse(args[0]) + _, err = parse.Parse(sqlStmt) if err != nil { return display.PrintErr(cmd, fmt.Errorf("failed to parse SQL statement: %s", err)) } return client.DialClient(cmd.Context(), cmd, dialFlags, func(ctx context.Context, cl clientType.Client, conf *config.KwilCliConfig) error { - res, err := cl.Query(ctx, args[0], params) + res, err := cl.Query(ctx, sqlStmt, params) if err != nil { return display.PrintErr(cmd, err) } @@ -85,6 +97,7 @@ func queryCmd() *cobra.Command { }, } + cmd.Flags().StringVarP(&stmt, "stmt", "s", "", "the SELECT statement to execute") cmd.Flags().StringArrayVarP(&namedParams, "param", "p", nil, `named parameters that will be used in the query. format: "key:type=value"`) cmd.Flags().BoolVar(&rpcAuth, "rpc-auth", false, "signals that the call is being made to a kwil node and should be authenticated with the private key") cmd.Flags().BoolVar(&gwAuth, "gateway-auth", false, "signals that the call is being made to a gateway and should be authenticated with the private key") @@ -106,5 +119,5 @@ func (r *respRelations) MarshalJSON() ([]byte, error) { } func (r *respRelations) MarshalText() ([]byte, error) { - return recordsToTable(r.Data.ExportToStringMap(), r.conf), nil + return recordsToTable(r.Data.ColumnNames, getStringRows(r.Data.Values), r.conf), nil } diff --git a/cmd/kwil-cli/cmds/tableprint.go b/cmd/kwil-cli/cmds/tableprint.go index 6f289bcc8f..7a620795ea 100644 --- a/cmd/kwil-cli/cmds/tableprint.go +++ b/cmd/kwil-cli/cmds/tableprint.go @@ -2,7 +2,6 @@ package cmds import ( "bytes" - "sort" "github.com/olekukonko/tablewriter" "github.com/spf13/cobra" @@ -56,39 +55,31 @@ func (t *tableConfig) apply(table *tablewriter.Table) { // recordsToTable converts records to a formatted table structure // that can be printed -func recordsToTable(data []map[string]string, c *tableConfig) []byte { +func recordsToTable(columns []string, rows [][]string, c *tableConfig) []byte { if c == nil { c = &tableConfig{} } - if len(data) == 0 { + if len(rows) == 0 { return []byte("No data to display.") } // collect headers - headers := make([]string, 0, len(data[0])) - for k := range data[0] { - headers = append(headers, k) - } - - // keep the headers in a sorted order - sort.Strings(headers) var buf bytes.Buffer table := tablewriter.NewWriter(&buf) - table.SetHeader(headers) + table.SetHeader(columns) table.SetAutoFormatHeaders(false) table.SetBorders( tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false}) c.apply(table) - for _, row := range data { - rs := make([]string, 0, len(headers)) - for _, h := range headers { - v := row[h] - if c.maxRowWidth > 0 && len(v) > c.maxRowWidth { - v = v[:c.maxRowWidth] + "..." + for _, row := range rows { + rs := make([]string, 0, len(columns)) + for _, col := range row { + if c.maxRowWidth > 0 && len(col) > c.maxRowWidth { + col = col[:c.maxRowWidth] + "..." } - rs = append(rs, v) + rs = append(rs, col) } table.Append(rs) } diff --git a/cmd/kwil-cli/cmds/utils/generate_key.go b/cmd/kwil-cli/cmds/utils/generate_key.go index 69bd401735..a5cb91e6b5 100644 --- a/cmd/kwil-cli/cmds/utils/generate_key.go +++ b/cmd/kwil-cli/cmds/utils/generate_key.go @@ -38,7 +38,7 @@ func generateKeyCmd() *cobra.Command { pubKeyBts := pubKey.Bytes() pubKeyHex := hex.EncodeToString(pubKeyBts) - address, err := auth.EthSecp256k1Authenticator{}.Identifier(crypto.EthereumAddressFromPubKey(pubKey.(*crypto.Secp256k1PublicKey))) + address, err := auth.EthSecp256k1Authenticator{}.Identifier(auth.GetUserSigner(pk).CompactID()) if err != nil { return display.PrintErr(cmd, err) } diff --git a/test/setup/jsonrpc_cli_driver.go b/test/setup/jsonrpc_cli_driver.go index 1ec633aae1..34648e54cf 100644 --- a/test/setup/jsonrpc_cli_driver.go +++ b/test/setup/jsonrpc_cli_driver.go @@ -312,7 +312,7 @@ func stringifyCLIArg(a any) string { } func (j *jsonRPCCLIDriver) ExecuteSQL(ctx context.Context, sql string, params map[string]any, opts ...client.TxOpt) (types.Hash, error) { - args := append([]string{"exec-sql"}, "--statement", sql) + args := append([]string{"exec-sql"}, "--stmt", sql) for k, v := range params { encoded, err := types.EncodeValue(v) if err != nil {