github.com/influxdata/influxdb/v2@v2.7.6/influxql/query/emitter.go (about) 1 package query 2 3 import ( 4 "github.com/influxdata/influxdb/v2/models" 5 ) 6 7 // Emitter reads from a cursor into rows. 8 type Emitter struct { 9 cur Cursor 10 chunkSize int 11 12 series Series 13 row *models.Row 14 columns []string 15 } 16 17 // NewEmitter returns a new instance of Emitter that pulls from itrs. 18 func NewEmitter(cur Cursor, chunkSize int) *Emitter { 19 columns := make([]string, len(cur.Columns())) 20 for i, col := range cur.Columns() { 21 columns[i] = col.Val 22 } 23 return &Emitter{ 24 cur: cur, 25 chunkSize: chunkSize, 26 columns: columns, 27 } 28 } 29 30 // Close closes the underlying iterators. 31 func (e *Emitter) Close() error { 32 return e.cur.Close() 33 } 34 35 // Emit returns the next row from the iterators. 36 func (e *Emitter) Emit() (*models.Row, bool, error) { 37 // Continually read from the cursor until it is exhausted. 38 for { 39 // Scan the next row. If there are no rows left, return the current row. 40 var row Row 41 if !e.cur.Scan(&row) { 42 if err := e.cur.Err(); err != nil { 43 return nil, false, err 44 } 45 r := e.row 46 e.row = nil 47 return r, false, nil 48 } 49 50 // If there's no row yet then create one. 51 // If the name and tags match the existing row, append to that row if 52 // the number of values doesn't exceed the chunk size. 53 // Otherwise return existing row and add values to next emitted row. 54 if e.row == nil { 55 e.createRow(row.Series, row.Values) 56 } else if e.series.SameSeries(row.Series) { 57 if e.chunkSize > 0 && len(e.row.Values) >= e.chunkSize { 58 r := e.row 59 r.Partial = true 60 e.createRow(row.Series, row.Values) 61 return r, true, nil 62 } 63 e.row.Values = append(e.row.Values, row.Values) 64 } else { 65 r := e.row 66 e.createRow(row.Series, row.Values) 67 return r, true, nil 68 } 69 } 70 } 71 72 // createRow creates a new row attached to the emitter. 73 func (e *Emitter) createRow(series Series, values []interface{}) { 74 e.series = series 75 e.row = &models.Row{ 76 Name: series.Name, 77 Tags: series.Tags.KeyValues(), 78 Columns: e.columns, 79 Values: [][]interface{}{values}, 80 } 81 }