github.com/netdata/go.d.plugin@v0.58.1/modules/postgres/do_query.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package postgres
     4  
     5  import (
     6  	"context"
     7  	"database/sql"
     8  )
     9  
    10  func (p *Postgres) doQueryRow(query string, v any) error {
    11  	ctx, cancel := context.WithTimeout(context.Background(), p.Timeout.Duration)
    12  	defer cancel()
    13  
    14  	return p.db.QueryRowContext(ctx, query).Scan(v)
    15  }
    16  
    17  func (p *Postgres) doDBQueryRow(db *sql.DB, query string, v any) error {
    18  	ctx, cancel := context.WithTimeout(context.Background(), p.Timeout.Duration)
    19  	defer cancel()
    20  
    21  	return db.QueryRowContext(ctx, query).Scan(v)
    22  }
    23  
    24  func (p *Postgres) doQuery(query string, assign func(column, value string, rowEnd bool)) error {
    25  	return p.doDBQuery(p.db, query, assign)
    26  }
    27  
    28  func (p *Postgres) doDBQuery(db *sql.DB, query string, assign func(column, value string, rowEnd bool)) error {
    29  	ctx, cancel := context.WithTimeout(context.Background(), p.Timeout.Duration)
    30  	defer cancel()
    31  
    32  	rows, err := db.QueryContext(ctx, query)
    33  	if err != nil {
    34  		return err
    35  	}
    36  	defer func() { _ = rows.Close() }()
    37  
    38  	return readRows(rows, assign)
    39  }
    40  
    41  func readRows(rows *sql.Rows, assign func(column, value string, rowEnd bool)) error {
    42  	if assign == nil {
    43  		return nil
    44  	}
    45  
    46  	columns, err := rows.Columns()
    47  	if err != nil {
    48  		return err
    49  	}
    50  
    51  	values := makeValues(len(columns))
    52  
    53  	for rows.Next() {
    54  		if err := rows.Scan(values...); err != nil {
    55  			return err
    56  		}
    57  		for i, l := 0, len(values); i < l; i++ {
    58  			assign(columns[i], valueToString(values[i]), i == l-1)
    59  		}
    60  	}
    61  	return rows.Err()
    62  }
    63  
    64  func valueToString(value any) string {
    65  	v, ok := value.(*sql.NullString)
    66  	if !ok || !v.Valid {
    67  		return ""
    68  	}
    69  	return v.String
    70  }
    71  
    72  func makeValues(size int) []any {
    73  	vs := make([]any, size)
    74  	for i := range vs {
    75  		vs[i] = &sql.NullString{}
    76  	}
    77  	return vs
    78  }