165 lines
4.8 KiB
Go
165 lines
4.8 KiB
Go
package postgresql
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"gitea.computernetthings.ru/yash/crypto_alert_bot/internal/entities"
|
|
"github.com/shopspring/decimal"
|
|
)
|
|
|
|
const saveAlertQuery = `
|
|
insert into alert(user_id, instrument_id, price, condition)
|
|
values ($1, $2, $3, $4)
|
|
returning id`
|
|
|
|
func (p *Postgresql) SaveAlert(ctx context.Context, alert *entities.Alert) (entities.AlertID, error) {
|
|
var id entities.AlertID
|
|
|
|
err := p.db.QueryRow(ctx, saveAlertQuery, alert.UserID, alert.Instrument.ID, alert.Price.String(), alert.Condition).Scan(&id)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to exec saveAlertQuery: %w", err)
|
|
}
|
|
|
|
return id, nil
|
|
}
|
|
|
|
const allActiveAlertsQuery = `
|
|
select a.id, a.user_id, a.price, a.condition, i.id, c_base.symbol, c_quote.symbol
|
|
from alert a
|
|
join instrument i on i.id = a.instrument_id
|
|
join currency c_base on c_base.id = i.base_currency_id
|
|
join currency c_quote on c_quote.id = i.quoted_currency_id
|
|
where a.active = true
|
|
order by a.id`
|
|
|
|
func (p *Postgresql) AllActiveAlerts(ctx context.Context) ([]entities.Alert, error) {
|
|
rows, err := p.db.Query(ctx, allActiveAlertsQuery)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to exec allActiveAlertsQuery: %w", err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
var alerts []entities.Alert
|
|
for rows.Next() {
|
|
var alert entities.Alert
|
|
var priceStr string
|
|
|
|
if err := rows.Scan(
|
|
&alert.ID, &alert.UserID, &priceStr, &alert.Condition,
|
|
&alert.Instrument.ID, &alert.Instrument.BaseCurrency, &alert.Instrument.QuoteCurrency,
|
|
); err != nil {
|
|
return nil, fmt.Errorf("failed to scan alert row: %w", err)
|
|
}
|
|
|
|
alert.Price, err = decimal.NewFromString(priceStr)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to parse alert price: %w", err)
|
|
}
|
|
|
|
alerts = append(alerts, alert)
|
|
}
|
|
|
|
return alerts, nil
|
|
}
|
|
|
|
const alertByIDQuery = `
|
|
select a.id, a.user_id, a.price, a.condition, i.id, c_base.symbol, c_quote.symbol
|
|
from alert a
|
|
join instrument i on i.id = a.instrument_id
|
|
join currency c_base on c_base.id = i.base_currency_id
|
|
join currency c_quote on c_quote.id = i.quoted_currency_id
|
|
where a.id = $1 and a.active = true`
|
|
|
|
func (p *Postgresql) AlertByID(ctx context.Context, id entities.AlertID) (*entities.Alert, error) {
|
|
var alert entities.Alert
|
|
var priceStr string
|
|
|
|
err := p.db.QueryRow(ctx, alertByIDQuery, id).Scan(
|
|
&alert.ID, &alert.UserID, &priceStr, &alert.Condition,
|
|
&alert.Instrument.ID, &alert.Instrument.BaseCurrency, &alert.Instrument.QuoteCurrency,
|
|
)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to exec alertByIDQuery: %w", err)
|
|
}
|
|
|
|
alert.Price, err = decimal.NewFromString(priceStr)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to parse alert price: %w", err)
|
|
}
|
|
|
|
return &alert, nil
|
|
}
|
|
|
|
const alertsByUserIDQuery = `
|
|
select a.id, a.user_id, a.price, a.condition, i.id, c_base.symbol, c_quote.symbol
|
|
from alert a
|
|
join instrument i on i.id = a.instrument_id
|
|
join currency c_base on c_base.id = i.base_currency_id
|
|
join currency c_quote on c_quote.id = i.quoted_currency_id
|
|
where a.user_id = $1 and a.active = true
|
|
order by a.id
|
|
offset $2 limit $3`
|
|
|
|
func (p *Postgresql) AlertsByUserID(ctx context.Context, userID entities.UserID, offset, limit int) ([]entities.Alert, error) {
|
|
rows, err := p.db.Query(ctx, alertsByUserIDQuery, userID, offset, limit)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to exec alertsByUserIDQuery: %w", err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
var alerts []entities.Alert
|
|
for rows.Next() {
|
|
var alert entities.Alert
|
|
var priceStr string
|
|
|
|
if err := rows.Scan(
|
|
&alert.ID, &alert.UserID, &priceStr, &alert.Condition,
|
|
&alert.Instrument.ID, &alert.Instrument.BaseCurrency, &alert.Instrument.QuoteCurrency,
|
|
); err != nil {
|
|
return nil, fmt.Errorf("failed to scan alert row: %w", err)
|
|
}
|
|
|
|
alert.Price, err = decimal.NewFromString(priceStr)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to parse alert price: %w", err)
|
|
}
|
|
|
|
alerts = append(alerts, alert)
|
|
}
|
|
|
|
return alerts, nil
|
|
}
|
|
|
|
const deleteAlertQuery = "update alert set active = false where id = $1"
|
|
|
|
func (p *Postgresql) DeleteAlert(ctx context.Context, id entities.AlertID) error {
|
|
_, err := p.db.Exec(ctx, deleteAlertQuery, id)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to exec deleteAlertQuery: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
const disableAlertQuery = "update alert set active = false where id = $1"
|
|
|
|
func (p *Postgresql) DisableAlert(ctx context.Context, id entities.AlertID) error {
|
|
_, err := p.db.Exec(ctx, disableAlertQuery, id)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to exec disableAlertQuery: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
const updateAlertPriceQuery = "update alert set price = $2 where id = $1"
|
|
|
|
func (p *Postgresql) UpdateAlertPrice(ctx context.Context, id entities.AlertID, price decimal.Decimal) error {
|
|
_, err := p.db.Exec(ctx, updateAlertPriceQuery, id, price.String())
|
|
if err != nil {
|
|
return fmt.Errorf("failed to exec updateAlertPriceQuery: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|