github.com/Jeffail/benthos/v3@v3.65.0/lib/processor/sql_deprecated.go (about) 1 package processor 2 3 import ( 4 "database/sql" 5 "fmt" 6 7 "github.com/Jeffail/benthos/v3/internal/tracing" 8 "github.com/Jeffail/benthos/v3/lib/message" 9 "github.com/Jeffail/benthos/v3/lib/types" 10 11 // SQL Drivers 12 _ "github.com/go-sql-driver/mysql" 13 ) 14 15 //------------------------------------------------------------------------------ 16 17 type sqlResultCodecDeprecated func(rows *sql.Rows, msg types.Message) error 18 19 func sqlResultJSONArrayCodecDeprecated(rows *sql.Rows, msg types.Message) error { 20 columnNames, err := rows.Columns() 21 if err != nil { 22 return err 23 } 24 jArray := []interface{}{} 25 for rows.Next() { 26 values := make([]interface{}, len(columnNames)) 27 valuesWrapped := make([]interface{}, len(columnNames)) 28 for i := range values { 29 valuesWrapped[i] = &values[i] 30 } 31 if err := rows.Scan(valuesWrapped...); err != nil { 32 return err 33 } 34 jObj := map[string]interface{}{} 35 for i, v := range values { 36 switch t := v.(type) { 37 case string: 38 jObj[columnNames[i]] = t 39 case []byte: 40 jObj[columnNames[i]] = string(t) 41 case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: 42 jObj[columnNames[i]] = t 43 case float32, float64: 44 jObj[columnNames[i]] = t 45 case bool: 46 jObj[columnNames[i]] = t 47 default: 48 jObj[columnNames[i]] = t 49 } 50 } 51 jArray = append(jArray, jObj) 52 } 53 if msg.Len() > 0 { 54 p := msg.Get(0) 55 msg.SetAll([]types.Part{p}) 56 return msg.Get(0).SetJSON(jArray) 57 } 58 msg.Append(message.NewPart(nil)) 59 return msg.Get(0).SetJSON(jArray) 60 } 61 62 func strToSQLResultCodecDeprecated(codec string) (sqlResultCodecDeprecated, error) { 63 switch codec { 64 case "json_array": 65 return sqlResultJSONArrayCodecDeprecated, nil 66 case "none": 67 return nil, nil 68 } 69 return nil, fmt.Errorf("unrecognised result codec: %v", codec) 70 } 71 72 //------------------------------------------------------------------------------ 73 74 func (s *SQL) doExecuteDeprecated(args ...interface{}) error { 75 _, err := s.query.Exec(args...) 76 return err 77 } 78 79 // processMessageDeprecated. 80 // TODO: V4 Remove this 81 func (s *SQL) processMessageDeprecated(msg types.Message) ([]types.Message, types.Response) { 82 s.mCount.Incr(1) 83 result := msg.Copy() 84 85 spans := tracing.CreateChildSpans(TypeSQL, result) 86 87 args := make([]interface{}, len(s.args)) 88 for i, v := range s.args { 89 args[i] = v.String(0, result) 90 } 91 var err error 92 if s.resCodecDeprecated == nil { 93 if err = s.doExecuteDeprecated(args...); err != nil { 94 err = fmt.Errorf("failed to execute query: %v", err) 95 } 96 } else { 97 var rows *sql.Rows 98 if rows, err = s.query.Query(args...); err == nil { 99 defer rows.Close() 100 if err = s.resCodecDeprecated(rows, result); err != nil { 101 err = fmt.Errorf("failed to apply result codec: %v", err) 102 } 103 } else { 104 err = fmt.Errorf("failed to execute query: %v", err) 105 } 106 } 107 if err != nil { 108 result.Iter(func(i int, p types.Part) error { 109 FlagErr(p, err) 110 spans[i].LogKV( 111 "event", "error", 112 "type", err.Error(), 113 ) 114 return nil 115 }) 116 s.log.Errorf("SQL error: %v\n", err) 117 s.mErr.Incr(1) 118 } 119 for _, s := range spans { 120 s.Finish() 121 } 122 123 s.mSent.Incr(int64(result.Len())) 124 s.mBatchSent.Incr(1) 125 126 return []types.Message{result}, nil 127 } 128 129 //------------------------------------------------------------------------------