2019-01-24 20:15:10 +00:00
|
|
|
// Copyright (C) 2019 Storj Labs, Inc.
|
2018-12-07 09:59:31 +00:00
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package satellitedb
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2019-02-01 18:50:12 +00:00
|
|
|
"fmt"
|
2018-12-07 09:59:31 +00:00
|
|
|
"time"
|
|
|
|
|
2019-02-01 18:50:12 +00:00
|
|
|
"github.com/zeebo/errs"
|
2019-01-28 19:45:25 +00:00
|
|
|
|
2018-12-07 09:59:31 +00:00
|
|
|
"storj.io/storj/pkg/bwagreement"
|
2019-01-28 19:45:25 +00:00
|
|
|
"storj.io/storj/pkg/pb"
|
2019-02-01 18:50:12 +00:00
|
|
|
"storj.io/storj/pkg/storj"
|
2018-12-07 09:59:31 +00:00
|
|
|
dbx "storj.io/storj/satellite/satellitedb/dbx"
|
|
|
|
)
|
|
|
|
|
|
|
|
type bandwidthagreement struct {
|
|
|
|
db *dbx.DB
|
|
|
|
}
|
|
|
|
|
2019-03-14 21:12:47 +00:00
|
|
|
func (b *bandwidthagreement) SaveOrder(ctx context.Context, rba *pb.Order) (err error) {
|
2019-03-12 20:57:21 +00:00
|
|
|
var saveOrderSQL = `INSERT INTO bwagreements ( serialnum, storage_node_id, uplink_id, action, total, created_at, expires_at ) VALUES ( ?, ?, ?, ?, ?, ?, ? )`
|
2019-03-14 21:12:47 +00:00
|
|
|
_, err = b.db.DB.ExecContext(ctx, b.db.Rebind(saveOrderSQL),
|
2019-03-12 20:57:21 +00:00
|
|
|
rba.PayerAllocation.SerialNumber+rba.StorageNodeId.String(),
|
|
|
|
rba.StorageNodeId,
|
|
|
|
rba.PayerAllocation.UplinkId,
|
|
|
|
int64(rba.PayerAllocation.Action),
|
|
|
|
rba.Total,
|
|
|
|
time.Now().UTC(),
|
|
|
|
time.Unix(rba.PayerAllocation.ExpirationUnixSec, 0),
|
2018-12-07 09:59:31 +00:00
|
|
|
)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2019-02-01 18:50:12 +00:00
|
|
|
//GetTotals returns stats about an uplink
|
|
|
|
func (b *bandwidthagreement) GetUplinkStats(ctx context.Context, from, to time.Time) (stats []bwagreement.UplinkStat, err error) {
|
|
|
|
|
|
|
|
var uplinkSQL = fmt.Sprintf(`SELECT uplink_id, SUM(total),
|
|
|
|
COUNT(CASE WHEN action = %d THEN total ELSE null END),
|
|
|
|
COUNT(CASE WHEN action = %d THEN total ELSE null END), COUNT(*)
|
|
|
|
FROM bwagreements WHERE created_at > ?
|
|
|
|
AND created_at <= ? GROUP BY uplink_id ORDER BY uplink_id`,
|
|
|
|
pb.BandwidthAction_PUT, pb.BandwidthAction_GET)
|
2019-03-14 21:12:47 +00:00
|
|
|
rows, err := b.db.DB.QueryContext(ctx, b.db.Rebind(uplinkSQL), from.UTC(), to.UTC())
|
2018-12-07 09:59:31 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2019-02-01 18:50:12 +00:00
|
|
|
defer func() { err = errs.Combine(err, rows.Close()) }()
|
|
|
|
for rows.Next() {
|
|
|
|
stat := bwagreement.UplinkStat{}
|
2019-03-12 20:57:21 +00:00
|
|
|
err := rows.Scan(&stat.NodeID, &stat.TotalBytes, &stat.PutActionCount, &stat.GetActionCount, &stat.TotalTransactions)
|
2019-01-28 19:45:25 +00:00
|
|
|
if err != nil {
|
2019-02-01 18:50:12 +00:00
|
|
|
return stats, err
|
2019-01-28 19:45:25 +00:00
|
|
|
}
|
2019-02-01 18:50:12 +00:00
|
|
|
stats = append(stats, stat)
|
2018-12-07 09:59:31 +00:00
|
|
|
}
|
2019-02-01 18:50:12 +00:00
|
|
|
return stats, nil
|
2018-12-07 09:59:31 +00:00
|
|
|
}
|
|
|
|
|
2019-02-01 18:50:12 +00:00
|
|
|
//GetTotals returns the sum of each bandwidth type after (exluding) a given date range
|
|
|
|
func (b *bandwidthagreement) GetTotals(ctx context.Context, from, to time.Time) (bwa map[storj.NodeID][]int64, err error) {
|
|
|
|
var getTotalsSQL = fmt.Sprintf(`SELECT storage_node_id,
|
|
|
|
SUM(CASE WHEN action = %d THEN total ELSE 0 END),
|
|
|
|
SUM(CASE WHEN action = %d THEN total ELSE 0 END),
|
|
|
|
SUM(CASE WHEN action = %d THEN total ELSE 0 END),
|
|
|
|
SUM(CASE WHEN action = %d THEN total ELSE 0 END),
|
|
|
|
SUM(CASE WHEN action = %d THEN total ELSE 0 END)
|
|
|
|
FROM bwagreements WHERE created_at > ? AND created_at <= ?
|
|
|
|
GROUP BY storage_node_id ORDER BY storage_node_id`, pb.BandwidthAction_PUT,
|
|
|
|
pb.BandwidthAction_GET, pb.BandwidthAction_GET_AUDIT,
|
|
|
|
pb.BandwidthAction_GET_REPAIR, pb.BandwidthAction_PUT_REPAIR)
|
2019-03-14 21:12:47 +00:00
|
|
|
rows, err := b.db.DB.QueryContext(ctx, b.db.Rebind(getTotalsSQL), from.UTC(), to.UTC())
|
2018-12-07 09:59:31 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2019-02-01 18:50:12 +00:00
|
|
|
defer func() { err = errs.Combine(err, rows.Close()) }()
|
2018-12-07 09:59:31 +00:00
|
|
|
|
2019-02-01 18:50:12 +00:00
|
|
|
totals := make(map[storj.NodeID][]int64)
|
|
|
|
for i := 0; rows.Next(); i++ {
|
2019-03-12 20:57:21 +00:00
|
|
|
var nodeID storj.NodeID
|
2019-02-01 18:50:12 +00:00
|
|
|
data := make([]int64, len(pb.BandwidthAction_value))
|
|
|
|
err := rows.Scan(&nodeID, &data[pb.BandwidthAction_PUT], &data[pb.BandwidthAction_GET],
|
|
|
|
&data[pb.BandwidthAction_GET_AUDIT], &data[pb.BandwidthAction_GET_REPAIR], &data[pb.BandwidthAction_PUT_REPAIR])
|
|
|
|
if err != nil {
|
|
|
|
return totals, err
|
|
|
|
}
|
2019-03-12 20:57:21 +00:00
|
|
|
totals[nodeID] = data
|
|
|
|
}
|
|
|
|
return totals, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
//GetExpired gets orders that are expired and were created before some time
|
2019-03-14 21:12:47 +00:00
|
|
|
func (b *bandwidthagreement) GetExpired(ctx context.Context, before time.Time, expiredAt time.Time) (orders []bwagreement.SavedOrder, err error) {
|
2019-03-12 20:57:21 +00:00
|
|
|
var getExpiredSQL = `SELECT serialnum, storage_node_id, uplink_id, action, total, created_at, expires_at
|
|
|
|
FROM bwagreements WHERE created_at < ? AND expires_at < ?`
|
2019-03-14 21:12:47 +00:00
|
|
|
rows, err := b.db.DB.QueryContext(ctx, b.db.Rebind(getExpiredSQL), before, expiredAt)
|
2019-03-12 20:57:21 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer func() { err = errs.Combine(err, rows.Close()) }()
|
|
|
|
for i := 0; rows.Next(); i++ {
|
|
|
|
o := bwagreement.SavedOrder{}
|
|
|
|
err = rows.Scan(&o.Serialnum, &o.StorageNodeID, &o.UplinkID, &o.Action, &o.Total, &o.CreatedAt, &o.ExpiresAt)
|
2019-01-28 19:45:25 +00:00
|
|
|
if err != nil {
|
2019-03-12 20:57:21 +00:00
|
|
|
break
|
2019-01-28 19:45:25 +00:00
|
|
|
}
|
2019-03-12 20:57:21 +00:00
|
|
|
orders = append(orders, o)
|
2018-12-07 09:59:31 +00:00
|
|
|
}
|
2019-03-12 20:57:21 +00:00
|
|
|
return orders, err
|
2018-12-07 09:59:31 +00:00
|
|
|
}
|
2019-01-10 18:30:55 +00:00
|
|
|
|
2019-03-12 20:57:21 +00:00
|
|
|
//DeleteExpired deletes orders that are expired and were created before some time
|
2019-03-14 21:12:47 +00:00
|
|
|
func (b *bandwidthagreement) DeleteExpired(ctx context.Context, before time.Time, expiredAt time.Time) error {
|
2019-03-12 20:57:21 +00:00
|
|
|
var deleteExpiredSQL = `DELETE FROM bwagreements WHERE created_at < ? AND expires_at < ?`
|
2019-03-14 21:12:47 +00:00
|
|
|
_, err := b.db.DB.ExecContext(ctx, b.db.Rebind(deleteExpiredSQL), before, expiredAt)
|
2019-03-12 20:57:21 +00:00
|
|
|
return err
|
2019-01-10 18:30:55 +00:00
|
|
|
}
|