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

     1  package queryresult
     2  
     3  import (
     4  	"github.com/turbot/steampipe-plugin-sdk/v5/grpc"
     5  	"github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto"
     6  	"time"
     7  )
     8  
     9  type ScanMetadataRow struct {
    10  	// the fields of this struct need to be public since these are populated by pgx using RowsToStruct
    11  	Connection   string                  `db:"connection,optional" json:"connection"`
    12  	Table        string                  `db:"table"  json:"table"`
    13  	CacheHit     bool                    `db:"cache_hit"  json:"cache_hit"`
    14  	RowsFetched  int64                   `db:"rows_fetched" json:"rows_fetched"`
    15  	HydrateCalls int64                   `db:"hydrate_calls" json:"hydrate_calls"`
    16  	StartTime    time.Time               `db:"start_time" json:"start_time"`
    17  	DurationMs   int64                   `db:"duration_ms" json:"duration_ms"`
    18  	Columns      []string                `db:"columns" json:"columns"`
    19  	Limit        *int64                  `db:"limit" json:"limit,omitempty"`
    20  	Quals        []grpc.SerializableQual `db:"quals" json:"quals,omitempty"`
    21  }
    22  
    23  func NewScanMetadataRow(connection string, table string, columns []string, quals map[string]*proto.Quals, startTime time.Time, diration time.Duration, limit int64, m *proto.QueryMetadata) ScanMetadataRow {
    24  	res := ScanMetadataRow{
    25  		Connection: connection,
    26  		Table:      table,
    27  		StartTime:  startTime,
    28  		DurationMs: diration.Milliseconds(),
    29  		Columns:    columns,
    30  		Quals:      grpc.QualMapToSerializableSlice(quals),
    31  	}
    32  	if limit == -1 {
    33  		res.Limit = nil
    34  	} else {
    35  		res.Limit = &limit
    36  	}
    37  	if m != nil {
    38  		res.CacheHit = m.CacheHit
    39  		res.RowsFetched = m.RowsFetched
    40  		res.HydrateCalls = m.HydrateCalls
    41  	}
    42  	return res
    43  }
    44  
    45  // AsResultRow returns the ScanMetadata as a map[string]interface which can be returned as a query result
    46  func (m ScanMetadataRow) AsResultRow() map[string]any {
    47  	res := map[string]any{
    48  		"connection":    m.Connection,
    49  		"table":         m.Table,
    50  		"cache_hit":     m.CacheHit,
    51  		"rows_fetched":  m.RowsFetched,
    52  		"hydrate_calls": m.HydrateCalls,
    53  		"start_time":    m.StartTime,
    54  		"duration_ms":   m.DurationMs,
    55  		"columns":       m.Columns,
    56  		"quals":         m.Quals,
    57  	}
    58  	// explicitly set limit to nil if needed (otherwise postgres returns `1`)
    59  	if m.Limit != nil {
    60  		res["limit"] = *m.Limit
    61  	} else {
    62  		res["limit"] = nil // Explicitly set nil
    63  	}
    64  	return res
    65  }
    66  
    67  type QueryRowSummary struct {
    68  	UncachedRowsFetched int64 `db:"uncached_rows_fetched" json:"uncached_rows_fetched"`
    69  	CachedRowsFetched   int64 `db:"cached_rows_fetched" json:"cached_rows_fetched"`
    70  	HydrateCalls        int64 `db:"hydrate_calls" json:"hydrate_calls"`
    71  	ScanCount           int64 `db:"scan_count" json:"scan_count"`
    72  	ConnectionCount     int64 `db:"connection_count" json:"connection_count"`
    73  	// map connections to the scans
    74  	connections map[string]struct{}
    75  }
    76  
    77  func NewQueryRowSummary() *QueryRowSummary {
    78  	return &QueryRowSummary{
    79  		connections: make(map[string]struct{}),
    80  	}
    81  }
    82  func (s *QueryRowSummary) AsResultRow() map[string]any {
    83  	res := map[string]any{
    84  		"uncached_rows_fetched": s.UncachedRowsFetched,
    85  		"cached_rows_fetched":   s.CachedRowsFetched,
    86  		"hydrate_calls":         s.HydrateCalls,
    87  		"scan_count":            s.ScanCount,
    88  		"connection_count":      s.ConnectionCount,
    89  	}
    90  
    91  	return res
    92  }
    93  
    94  func (s *QueryRowSummary) Update(m ScanMetadataRow) {
    95  	if m.CacheHit {
    96  		s.CachedRowsFetched += m.RowsFetched
    97  	} else {
    98  		s.UncachedRowsFetched += m.RowsFetched
    99  	}
   100  	s.HydrateCalls += m.HydrateCalls
   101  	s.ScanCount++
   102  	s.connections[m.Connection] = struct{}{}
   103  	s.ConnectionCount = int64(len(s.connections))
   104  }