Files
steam_analyzer/internal/repository/postgres.go
2026-01-17 22:45:02 +03:00

203 lines
3.7 KiB
Go

package repository
import (
"context"
"fmt"
"steam_analyzer/internal/domain"
"steam_analyzer/pkg/postgresql"
"github.com/google/uuid"
)
type PostgresDB struct {
conn postgresql.PGXPool
}
func NewPostgresDB(conn postgresql.PGXPool) *PostgresDB {
return &PostgresDB{
conn: conn,
}
}
func (db PostgresDB) InitDatabaseTables(ctx context.Context) error {
createTable := `
CREATE TABLE IF NOT EXISTS item (
id UUID PRIMARY KEY,
name TEXT,
class_id TEXT UNIQUE NOT NULL,
game_id INTEGER NOT NULL,
type_id INTEGER
);`
_, err := db.conn.Exec(ctx, createTable)
if err != nil {
return err
}
createTable = `
CREATE TABLE IF NOT EXISTS item_history (
item_id UUID REFERENCES item(id),
price REAL,
count INTEGER,
date TIMESTAMPTZ NOT NULL,
PRIMARY KEY (item_id, date)
);`
_, err = db.conn.Exec(ctx, createTable)
if err != nil {
return err
}
return nil
}
func (db PostgresDB) AddItem(ctx context.Context, item domain.DBItem) error {
query := `
INSERT INTO item (id, name, class_id, game_id)
VALUES ($1, $2, $3, $4)
`
_, err := db.conn.Exec(ctx, query,
item.ID,
item.Name,
item.ClassID,
item.GameID,
)
if err != nil {
return err
}
return nil
}
func (db PostgresDB) AddItemHistory(ctx context.Context, dbItemHistory domain.DBItemHistory) error {
query := `
INSERT INTO item_history (item_id, price, count, date)
VALUES ($1, $2, $3, $4)
`
_, err := db.conn.Exec(ctx, query,
dbItemHistory.ItemID,
dbItemHistory.Price,
dbItemHistory.Count,
dbItemHistory.Date,
)
if err != nil {
return err
}
return nil
}
func (db PostgresDB) GetItemByClassID(ctx context.Context, classID string) (*domain.SteamItem, error) {
query := `
SELECT
id,
name,
class_id
FROM item
WHERE class_id = $1
`
row := db.conn.QueryRow(ctx, query, classID)
var steamItem domain.SteamItem
err := row.Scan(
&steamItem.ID,
&steamItem.Name,
&steamItem.ClassID,
)
if err != nil {
return nil, err
}
return &steamItem, nil
}
func (db PostgresDB) GetItemPriceHistoryByID(ctx context.Context, itemID uuid.UUID, limit int, offset int) ([]domain.ItemPriceHistory, error) {
query := `
SELECT
price,
count,
date
FROM item_history
WHERE item_id = $1
ORDER BY date DESC
LIMIT $2
OFFSET $3
`
var itemPriceHistory []domain.ItemPriceHistory
rows, err := db.conn.Query(ctx, query,
itemID,
limit,
offset,
)
if err != nil {
return nil, err
}
for rows.Next() {
var steamItemPriceHistory domain.ItemPriceHistory
err := rows.Scan(
&steamItemPriceHistory.Price,
&steamItemPriceHistory.Count,
&steamItemPriceHistory.Date,
)
if err != nil {
fmt.Println("error while iterating rows", err)
continue
}
itemPriceHistory = append(itemPriceHistory, steamItemPriceHistory)
}
return itemPriceHistory, nil
}
func (db PostgresDB) GetItemsWithLastPriceByName(ctx context.Context, name string) ([]ItemWithLastPrice, error) {
query := `
SELECT
class_id,
name,
price,
last_date
FROM item
JOIN (
SELECT
item_id,
MAX(price) AS price,
MAX(date) AS last_date
FROM item_history
GROUP BY item_id
) as last_prices
ON item.id = last_prices.item_id
WHERE LOWER(name) like $1
ORDER BY last_date DESC;
`
rows, err := db.conn.Query(ctx, query,
"%"+name+"%",
)
if err != nil {
return nil, err
}
var itemsWithLastPrice []ItemWithLastPrice
var itemWithLastPrice ItemWithLastPrice
for rows.Next() {
err := rows.Scan(
&itemWithLastPrice.ClassID,
&itemWithLastPrice.Name,
&itemWithLastPrice.Price,
&itemWithLastPrice.Date,
)
if err != nil {
fmt.Println("error while scaning row", err)
continue
}
itemsWithLastPrice = append(itemsWithLastPrice, itemWithLastPrice)
}
return itemsWithLastPrice, nil
}