func (p *pgSerDe) SeriesQuery(ds *rrd.DataSource, from, to time.Time, maxPoints int64) (dsl.Series, error) { rra := ds.BestRRA(from, to, maxPoints) // If from/to are nil - assign the rra boundaries rraEarliest := rra.Begins(rra.Latest()) if from.IsZero() || rraEarliest.After(from) { from = rraEarliest } // Note that seriesQuerySqlUsingViewAndSeries() will modify "to" // to be the earliest of "to" or "LastUpdate". dps := &dbSeries{db: p, ds: ds, rra: rra, from: from, to: to, maxPoints: maxPoints} return dsl.Series(dps), nil }
func (p *pgSerDe) fetchRoundRobinArchives(ds *rrd.DataSource) ([]*rrd.RoundRobinArchive, error) { const sql = `SELECT id, ds_id, cf, steps_per_row, size, width, xff, value, duration_ms, latest FROM %[1]srra rra WHERE ds_id = $1` rows, err := p.dbConn.Query(fmt.Sprintf(sql, p.prefix), ds.Id()) if err != nil { log.Printf("fetchRoundRobinArchives(): error querying database: %v", err) return nil, err } defer rows.Close() var rras []*rrd.RoundRobinArchive for rows.Next() { if rra, err := roundRobinArchiveFromRow(rows, ds.Step()); err == nil { rras = append(rras, rra) } else { log.Printf("fetchRoundRobinArchives(): error: %v", err) return nil, err } } return rras, nil }
func (p *pgSerDe) FlushDataSource(ds *rrd.DataSource) error { for _, rra := range ds.RRAs() { if rra.PointCount() > 0 { if err := p.flushRoundRobinArchive(rra); err != nil { log.Printf("FlushDataSource(): error flushing RRA, probable data loss: %v", err) return err } } } if debug { log.Printf("FlushDataSource(): Id %d: LastUpdate: %v, LastDs: %v, Value: %v, Duration: %v", ds.Id(), ds.LastUpdate(), ds.LastDs(), ds.Value(), ds.Duration()) } durationMs := ds.Duration().Nanoseconds() / 1000000 if rows, err := p.sql7.Query(ds.LastUpdate(), ds.LastDs(), ds.Value(), durationMs, ds.Id()); err != nil { log.Printf("FlushDataSource(): database error: %v flushing data source %#v", err, ds) return err } else { rows.Close() } return nil }