(ctx context.Context, initData *query.InitData, resolvedQuery *modconfig.ResolvedQuery)
| 133 | } |
| 134 | |
| 135 | func executeQuery(ctx context.Context, initData *query.InitData, resolvedQuery *modconfig.ResolvedQuery) (error, int) { |
| 136 | utils.LogTime("query.execute.executeQuery start") |
| 137 | defer utils.LogTime("query.execute.executeQuery end") |
| 138 | |
| 139 | var snap *steampipeconfig.SteampipeSnapshot |
| 140 | |
| 141 | // the db executor sends result data over resultsStreamer |
| 142 | resultsStreamer, err := db_common.ExecuteQuery(ctx, initData.Client, resolvedQuery.ExecuteSQL, resolvedQuery.Args...) |
| 143 | if err != nil { |
| 144 | return err, 0 |
| 145 | } |
| 146 | |
| 147 | rowErrors := 0 // get the number of rows that returned an error |
| 148 | // print the data as it comes |
| 149 | for r := range resultsStreamer.Results { |
| 150 | // wrap the result from pipe-fittings with our wrapper that has idempotent Close |
| 151 | wrapped := queryresult.WrapResult(r) |
| 152 | |
| 153 | // if the output format is snapshot or export is set or share/snapshot args are set, we need to generate a snapshot |
| 154 | if needSnapshot() { |
| 155 | snap, err = snapshot.QueryResultToSnapshot(ctx, r, resolvedQuery, initData.Client.GetRequiredSessionSearchPath(), initData.StartTime) |
| 156 | if err != nil { |
| 157 | return err, 0 |
| 158 | } |
| 159 | |
| 160 | // re-generate the query result from the snapshot. since the row stream in the actual queryresult has been exhausted(while generating the snapshot), |
| 161 | // we need to re-generate it for other output formats |
| 162 | newQueryResult, err := snapshot.SnapshotToQueryResult[pqueryresult.TimingContainer](snap, initData.StartTime) |
| 163 | if err != nil { |
| 164 | return err, 0 |
| 165 | } |
| 166 | |
| 167 | // if the output format is snapshot we don't call the querydisplay code in pipe-fittings, instead we |
| 168 | // generate the snapshot and display it to stdout |
| 169 | outputFormat := viper.GetString(pconstants.ArgOutput) |
| 170 | if outputFormat == pconstants.OutputFormatSnapshot || outputFormat == pconstants.OutputFormatSteampipeSnapshotShort { |
| 171 | |
| 172 | // display the snapshot as JSON |
| 173 | encoder := json.NewEncoder(os.Stdout) |
| 174 | encoder.SetIndent("", " ") |
| 175 | encoder.SetEscapeHTML(false) |
| 176 | if err := encoder.Encode(snap); err != nil { |
| 177 | //nolint:forbidigo // acceptable |
| 178 | fmt.Print("Error displaying result as snapshot", err) |
| 179 | return err, 0 |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | // if we need to export the snapshot, we export it directly from here |
| 184 | if viper.IsSet(pconstants.ArgExport) { |
| 185 | exportArgs := viper.GetStringSlice(pconstants.ArgExport) |
| 186 | exportMsg, err := initData.ExportManager.DoExport(ctx, "query", snap, exportArgs) |
| 187 | if err != nil { |
| 188 | return err, 0 |
| 189 | } |
| 190 | // print the location where the file is exported |
| 191 | if len(exportMsg) > 0 && viper.GetBool(pconstants.ArgProgress) { |
| 192 | fmt.Printf("\n") //nolint:forbidigo // intentional use of fmt |
no test coverage detected