203 lines
3.7 KiB
Go
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
|
|
}
|