github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/pkg/steampipeconfig/options/query.go (about)

     1  package options
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/hashicorp/hcl/v2"
     6  	"golang.org/x/exp/maps"
     7  	"strings"
     8  
     9  	"github.com/turbot/go-kit/helpers"
    10  	"github.com/turbot/steampipe/pkg/constants"
    11  )
    12  
    13  type Query struct {
    14  	Output       *string `hcl:"output" cty:"query_output"`
    15  	Separator    *string `hcl:"separator" cty:"query_separator"`
    16  	Header       *bool   `hcl:"header" cty:"query_header"`
    17  	Multi        *bool   `hcl:"multi" cty:"query_multi"`
    18  	Timing       *string `cty:"query_timing"` // parsed manually
    19  	AutoComplete *bool   `hcl:"autocomplete" cty:"query_autocomplete"`
    20  }
    21  
    22  func (t *Query) SetBaseProperties(otherOptions Options) {
    23  	if helpers.IsNil(otherOptions) {
    24  		return
    25  	}
    26  	if o, ok := otherOptions.(*Query); ok {
    27  		if t.Output == nil && o.Output != nil {
    28  			t.Output = o.Output
    29  		}
    30  		if t.Separator == nil && o.Separator != nil {
    31  			t.Separator = o.Separator
    32  		}
    33  		if t.Header == nil && o.Header != nil {
    34  			t.Header = o.Header
    35  		}
    36  		if t.Multi == nil && o.Multi != nil {
    37  			t.Multi = o.Multi
    38  		}
    39  		if t.Timing == nil && o.Timing != nil {
    40  			t.Timing = o.Timing
    41  		}
    42  		if t.AutoComplete == nil && o.AutoComplete != nil {
    43  			t.AutoComplete = o.AutoComplete
    44  		}
    45  	}
    46  }
    47  
    48  // ConfigMap creates a config map that can be merged with viper
    49  func (t *Query) ConfigMap() map[string]interface{} {
    50  	// only add keys which are non null
    51  	res := map[string]interface{}{}
    52  	if t.Output != nil {
    53  		res[constants.ArgOutput] = t.Output
    54  	}
    55  	if t.Separator != nil {
    56  		res[constants.ArgSeparator] = t.Separator
    57  	}
    58  	if t.Header != nil {
    59  		res[constants.ArgHeader] = t.Header
    60  	}
    61  	if t.Multi != nil {
    62  		res[constants.ArgMultiLine] = t.Multi
    63  	}
    64  	if t.Timing != nil {
    65  		res[constants.ArgTiming] = *t.Timing
    66  	}
    67  	if t.AutoComplete != nil {
    68  		res[constants.ArgAutoComplete] = t.AutoComplete
    69  	}
    70  	return res
    71  }
    72  
    73  // Merge :: merge other options over the top of this options object
    74  // i.e. if a property is set in otherOptions, it takes precedence
    75  func (t *Query) Merge(otherOptions Options) {
    76  	if _, ok := otherOptions.(*Query); !ok {
    77  		return
    78  	}
    79  	switch o := otherOptions.(type) {
    80  	case *Query:
    81  		if o.Output != nil {
    82  			t.Output = o.Output
    83  		}
    84  		if o.Separator != nil {
    85  			t.Separator = o.Separator
    86  		}
    87  		if o.Header != nil {
    88  			t.Header = o.Header
    89  		}
    90  		if o.Multi != nil {
    91  			t.Multi = o.Multi
    92  		}
    93  		if o.Timing != nil {
    94  			t.Timing = o.Timing
    95  		}
    96  		if o.AutoComplete != nil {
    97  			t.AutoComplete = o.AutoComplete
    98  		}
    99  	}
   100  }
   101  
   102  func (t *Query) String() string {
   103  	if t == nil {
   104  		return ""
   105  	}
   106  	var str []string
   107  	if t.Output == nil {
   108  		str = append(str, "  Output: nil")
   109  	} else {
   110  		str = append(str, fmt.Sprintf("  Output: %s", *t.Output))
   111  	}
   112  	if t.Separator == nil {
   113  		str = append(str, "  Separator: nil")
   114  	} else {
   115  		str = append(str, fmt.Sprintf("  Separator: %s", *t.Separator))
   116  	}
   117  	if t.Header == nil {
   118  		str = append(str, "  Header: nil")
   119  	} else {
   120  		str = append(str, fmt.Sprintf("  Header: %v", *t.Header))
   121  	}
   122  	if t.Multi == nil {
   123  		str = append(str, "  Multi: nil")
   124  	} else {
   125  		str = append(str, fmt.Sprintf("  Multi: %v", *t.Multi))
   126  	}
   127  	if t.Timing == nil {
   128  		str = append(str, "  Timing: nil")
   129  	} else {
   130  		str = append(str, fmt.Sprintf("  Timing: %v", *t.Timing))
   131  	}
   132  	if t.AutoComplete == nil {
   133  		str = append(str, "  AutoComplete: nil")
   134  	} else {
   135  		str = append(str, fmt.Sprintf("  AutoComplete: %v", *t.AutoComplete))
   136  	}
   137  	return strings.Join(str, "\n")
   138  }
   139  
   140  func (t *Query) SetTiming(flag string, r hcl.Range) hcl.Diagnostics {
   141  	// check the value is valid
   142  	if _, ok := constants.QueryTimingValueLookup[flag]; !ok {
   143  		return hcl.Diagnostics{
   144  			&hcl.Diagnostic{
   145  				Severity: hcl.DiagError,
   146  				Summary:  fmt.Sprintf("Invalid timing value '%s', query options support: %s", flag, strings.Join(maps.Keys(constants.QueryTimingValueLookup), ", ")),
   147  				Subject:  &r,
   148  			},
   149  		}
   150  	}
   151  	t.Timing = &flag
   152  
   153  	return nil
   154  }