2024-05-22 15:45:38 +00:00
|
|
|
package monero
|
2024-05-03 17:11:56 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2024-05-03 18:11:21 +00:00
|
|
|
"slices"
|
2024-05-03 17:11:56 +00:00
|
|
|
"strings"
|
2024-07-06 18:28:44 +00:00
|
|
|
|
|
|
|
"github.com/ditatompel/xmr-remote-nodes/internal/database"
|
2024-05-03 17:11:56 +00:00
|
|
|
|
|
|
|
"github.com/google/uuid"
|
|
|
|
)
|
|
|
|
|
2024-05-30 06:40:57 +00:00
|
|
|
const ProberAPIKey = "X-Prober-Api-Key" // HTTP header key
|
|
|
|
|
2024-07-06 20:25:30 +00:00
|
|
|
type proberRepo struct {
|
2024-05-03 17:11:56 +00:00
|
|
|
db *database.DB
|
|
|
|
}
|
|
|
|
|
|
|
|
type Prober struct {
|
2024-05-30 05:46:33 +00:00
|
|
|
ID int64 `json:"id" db:"id"`
|
2024-05-03 17:11:56 +00:00
|
|
|
Name string `json:"name" db:"name"`
|
2024-06-09 20:03:23 +00:00
|
|
|
APIKey uuid.UUID `json:"api_key" db:"api_key"`
|
|
|
|
LastSubmitTS int64 `json:"last_submit_ts" db:"last_submit_ts"`
|
2024-05-03 17:11:56 +00:00
|
|
|
}
|
|
|
|
|
2024-05-27 00:17:27 +00:00
|
|
|
// Initializes a new ProberRepository
|
|
|
|
//
|
|
|
|
// NOTE: This "prober" is different with "probe" which is used to fetch a new job
|
2024-07-06 20:25:30 +00:00
|
|
|
func NewProber() *proberRepo {
|
|
|
|
return &proberRepo{db: database.GetDB()}
|
2024-05-03 17:11:56 +00:00
|
|
|
}
|
|
|
|
|
2024-05-27 00:17:27 +00:00
|
|
|
// Add a new prober machine
|
2024-07-06 20:25:30 +00:00
|
|
|
func (r *proberRepo) Add(name string) (Prober, error) {
|
2024-05-18 12:03:56 +00:00
|
|
|
apiKey := uuid.New()
|
2024-05-19 21:22:58 +00:00
|
|
|
query := `
|
|
|
|
INSERT INTO tbl_prober (
|
|
|
|
name,
|
|
|
|
api_key,
|
|
|
|
last_submit_ts
|
|
|
|
) VALUES (
|
|
|
|
?,
|
|
|
|
?,
|
|
|
|
?
|
|
|
|
)`
|
2024-05-30 13:14:16 +00:00
|
|
|
_, err := r.db.Exec(query, name, apiKey, 0)
|
2024-05-03 17:11:56 +00:00
|
|
|
if err != nil {
|
2024-05-18 12:03:56 +00:00
|
|
|
return Prober{}, err
|
2024-05-03 17:11:56 +00:00
|
|
|
}
|
2024-06-09 20:03:23 +00:00
|
|
|
return Prober{Name: name, APIKey: apiKey}, nil
|
2024-05-03 17:11:56 +00:00
|
|
|
}
|
|
|
|
|
2024-05-27 00:17:27 +00:00
|
|
|
// Edit an existing prober
|
2024-07-06 20:25:30 +00:00
|
|
|
func (r *proberRepo) Edit(id int, name string) error {
|
2024-05-07 16:23:31 +00:00
|
|
|
query := `UPDATE tbl_prober SET name = ? WHERE id = ?`
|
2024-05-30 13:14:16 +00:00
|
|
|
res, err := r.db.Exec(query, name, id)
|
2024-05-18 12:50:20 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
row, err := res.RowsAffected()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if row == 0 {
|
|
|
|
return fmt.Errorf("no rows affected")
|
|
|
|
}
|
2024-05-07 16:23:31 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2024-05-27 00:17:27 +00:00
|
|
|
// Delete an existing prober
|
2024-07-06 20:25:30 +00:00
|
|
|
func (r *proberRepo) Delete(id int) error {
|
2024-05-30 13:14:16 +00:00
|
|
|
res, err := r.db.Exec(`DELETE FROM tbl_prober WHERE id = ?`, id)
|
2024-05-18 12:39:27 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
row, err := res.RowsAffected()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if row == 0 {
|
|
|
|
return fmt.Errorf("no rows affected")
|
|
|
|
}
|
2024-05-07 16:23:31 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2024-05-27 00:17:27 +00:00
|
|
|
type QueryProbers struct {
|
2024-05-17 17:56:13 +00:00
|
|
|
Search string
|
|
|
|
SortBy string
|
|
|
|
SortDirection string
|
|
|
|
}
|
|
|
|
|
2024-05-30 13:14:16 +00:00
|
|
|
func (q QueryProbers) toSQL() (args []interface{}, where, sortBy, sortDirection string) {
|
|
|
|
wq := []string{}
|
2024-05-17 17:56:13 +00:00
|
|
|
if q.Search != "" {
|
2024-05-30 13:14:16 +00:00
|
|
|
wq = append(wq, "(name LIKE ? OR api_key LIKE ?)")
|
|
|
|
args = append(args, "%"+q.Search+"%", "%"+q.Search+"%")
|
2024-05-03 17:11:56 +00:00
|
|
|
}
|
2024-05-30 13:14:16 +00:00
|
|
|
if len(wq) > 0 {
|
|
|
|
where = "WHERE " + strings.Join(wq, " AND ")
|
2024-05-03 17:11:56 +00:00
|
|
|
}
|
|
|
|
|
2024-05-30 13:14:16 +00:00
|
|
|
as := []string{"id", "last_submit_ts"}
|
|
|
|
sortBy = "last_submit_ts"
|
|
|
|
if slices.Contains(as, q.SortBy) {
|
2024-05-03 18:11:21 +00:00
|
|
|
sortBy = q.SortBy
|
|
|
|
}
|
2024-05-30 13:14:16 +00:00
|
|
|
sortDirection = "DESC"
|
2024-05-03 18:11:21 +00:00
|
|
|
if q.SortDirection == "asc" {
|
|
|
|
sortDirection = "ASC"
|
|
|
|
}
|
|
|
|
|
2024-05-30 13:14:16 +00:00
|
|
|
return args, where, sortBy, sortDirection
|
|
|
|
}
|
|
|
|
|
2024-07-06 20:25:30 +00:00
|
|
|
func (r *proberRepo) Probers(q QueryProbers) ([]Prober, error) {
|
2024-05-30 13:14:16 +00:00
|
|
|
args, where, sortBy, sortDirection := q.toSQL()
|
|
|
|
|
|
|
|
var probers []Prober
|
|
|
|
|
2024-05-19 21:22:58 +00:00
|
|
|
query := fmt.Sprintf(`
|
|
|
|
SELECT
|
|
|
|
id,
|
|
|
|
name,
|
|
|
|
api_key,
|
|
|
|
last_submit_ts
|
|
|
|
FROM
|
|
|
|
tbl_prober
|
|
|
|
%s -- where clause if any
|
|
|
|
ORDER BY %s %s`, where, sortBy, sortDirection)
|
2024-05-03 17:11:56 +00:00
|
|
|
|
2024-05-30 13:14:16 +00:00
|
|
|
row, err := r.db.Query(query, args...)
|
2024-05-03 17:11:56 +00:00
|
|
|
if err != nil {
|
|
|
|
return probers, err
|
|
|
|
}
|
|
|
|
defer row.Close()
|
|
|
|
|
|
|
|
for row.Next() {
|
2024-05-27 00:17:27 +00:00
|
|
|
var p Prober
|
2024-06-09 20:03:23 +00:00
|
|
|
err = row.Scan(&p.ID, &p.Name, &p.APIKey, &p.LastSubmitTS)
|
2024-05-03 17:11:56 +00:00
|
|
|
if err != nil {
|
|
|
|
return probers, err
|
|
|
|
}
|
2024-05-27 00:17:27 +00:00
|
|
|
probers = append(probers, p)
|
2024-05-03 17:11:56 +00:00
|
|
|
}
|
|
|
|
return probers, nil
|
|
|
|
}
|
2024-05-04 12:52:22 +00:00
|
|
|
|
2024-07-06 20:25:30 +00:00
|
|
|
func (r *proberRepo) CheckAPI(key string) (Prober, error) {
|
2024-05-27 00:17:27 +00:00
|
|
|
var p Prober
|
2024-05-19 21:22:58 +00:00
|
|
|
query := `
|
|
|
|
SELECT
|
|
|
|
id,
|
|
|
|
name,
|
|
|
|
api_key,
|
|
|
|
last_submit_ts
|
|
|
|
FROM
|
|
|
|
tbl_prober
|
|
|
|
WHERE
|
|
|
|
api_key = ?
|
|
|
|
LIMIT 1`
|
2024-06-09 20:03:23 +00:00
|
|
|
err := r.db.QueryRow(query, key).Scan(&p.ID, &p.Name, &p.APIKey, &p.LastSubmitTS)
|
2024-05-27 00:17:27 +00:00
|
|
|
return p, err
|
2024-05-04 12:52:22 +00:00
|
|
|
}
|