diff --git a/featctl/cmd/get_historical_feature.go b/featctl/cmd/get_historical_feature.go index fca527329..34cd40788 100644 --- a/featctl/cmd/get_historical_feature.go +++ b/featctl/cmd/get_historical_feature.go @@ -9,6 +9,7 @@ import ( ) var getHistoricalFeatureOpt types.ExportFeatureValuesOpt +var getHistoricalFeatureOutput *string var getHistoricalFeatureCmd = &cobra.Command{ Use: "historical-feature", @@ -20,13 +21,16 @@ var getHistoricalFeatureCmd = &cobra.Command{ if !cmd.Flags().Changed("limit") { getHistoricalFeatureOpt.Limit = nil } + if !cmd.Flags().Changed("output") { + getHistoricalFeatureOutput = stringPtr(ASCIITable) + } }, Run: func(cmd *cobra.Command, args []string) { ctx := context.Background() oomStore := mustOpenOomStore(ctx, oomStoreCfg) defer oomStore.Close() - if err := getHistoricalFeature(ctx, oomStore, getHistoricalFeatureOpt); err != nil { + if err := getHistoricalFeature(ctx, oomStore, getHistoricalFeatureOpt, *getHistoricalFeatureOutput); err != nil { log.Fatalf("failed exporting features: %v\n", err) } }, @@ -44,4 +48,5 @@ func init() { getHistoricalFeatureOpt.Limit = flags.Uint64P("limit", "l", 0, "max records to export") getHistoricalFeatureOpt.GroupRevision = flags.Int64P("revision", "r", 0, "feature group revision") + getHistoricalFeatureOutput = flags.StringP("output", "o", "", "output format") } diff --git a/featctl/cmd/get_historical_feature_helper.go b/featctl/cmd/get_historical_feature_helper.go index fd69ad9de..ccb7064cd 100644 --- a/featctl/cmd/get_historical_feature_helper.go +++ b/featctl/cmd/get_historical_feature_helper.go @@ -3,19 +3,39 @@ package cmd import ( "context" "encoding/csv" + "fmt" "os" + "github.com/olekukonko/tablewriter" "github.com/oom-ai/oomstore/pkg/oomstore" "github.com/oom-ai/oomstore/pkg/oomstore/types" "github.com/spf13/cast" ) -func getHistoricalFeature(ctx context.Context, store *oomstore.OomStore, opt types.ExportFeatureValuesOpt) error { +func getHistoricalFeature(ctx context.Context, store *oomstore.OomStore, opt types.ExportFeatureValuesOpt, output string) error { fields, stream, err := store.ExportFeatureValues(ctx, opt) if err != nil { return err } + if err := printHistoricalFeatures(fields, stream, output); err != nil { + return fmt.Errorf("failed printing historical features: %+v", err) + } + return nil +} + +func printHistoricalFeatures(fields []string, stream <-chan *types.RawFeatureValueRecord, output string) error { + switch output { + case CSV: + return printHistoricalFeaturesInCSV(fields, stream) + case ASCIITable: + return printHistoricalFeaturesInASCIITable(fields, stream) + default: + return fmt.Errorf("unsupported output format %s", output) + } +} + +func printHistoricalFeaturesInCSV(fields []string, stream <-chan *types.RawFeatureValueRecord) error { w := csv.NewWriter(os.Stdout) defer w.Flush() @@ -30,5 +50,21 @@ func getHistoricalFeature(ctx context.Context, store *oomstore.OomStore, opt typ return err } } - return err + return nil +} + +func printHistoricalFeaturesInASCIITable(fields []string, stream <-chan *types.RawFeatureValueRecord) error { + table := tablewriter.NewWriter(os.Stdout) + table.SetHeader(fields) + table.SetAutoFormatHeaders(false) + + for item := range stream { + if item.Error != nil { + return item.Error + } + table.Append(cast.ToStringSlice(item.Record)) + } + + table.Render() + return nil } diff --git a/featctl/test/test_get_historical_feature.sh b/featctl/test/test_get_historical_feature.sh index 0fa53fff8..7509eef2c 100755 --- a/featctl/test/test_get_historical_feature.sh +++ b/featctl/test/test_get_historical_feature.sh @@ -18,16 +18,16 @@ expected='device,price 8,6500 9,4500 ' -#actual=$(featctl get historical-feature --group phone --feature price) -#assert_eq "$case" "$expected" "$actual" -# -#case='get with limit' -#expected='device,price -#1,3999 -#2,5299 -#3,3999 -#4,1999 -#5,999 -#' -#actual=$(featctl get historical-feature --group phone --feature price --limit 5) -#assert_eq "$case" "$expected" "$actual" +actual=$(featctl get historical-feature --group phone --feature price -o csv) +assert_eq "$case" "$expected" "$actual" + +case='get with limit' +expected='device,price +1,3999 +2,5299 +3,3999 +4,1999 +5,999 +' +actual=$(featctl get historical-feature --group phone --feature price --limit 5 -o csv) +assert_eq "$case" "$expected" "$actual"