Files
2026-01-17 22:45:02 +03:00

222 lines
4.0 KiB
Go

// Package repository for repositorie's
package repository
import (
"database/sql"
"fmt"
"log"
"steam_analyzer/internal/domain"
"time"
"github.com/google/uuid"
)
type SQLLiteDatabase struct {
db *sql.DB
}
func NewSQLLiteDatabase(db *sql.DB) *SQLLiteDatabase {
return &SQLLiteDatabase{
db: db,
}
}
func ConnectOrCreateDatabase() *sql.DB {
// Connect to (or create) the SQLite database
db, err := sql.Open("sqlite3", "./steam_items.db")
if err != nil {
log.Fatal(err)
}
return db
}
func (sqldb SQLLiteDatabase) InitDatabaseTables() 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 := sqldb.db.Exec(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 DATETIME NOT NULL,
PRIMARY KEY (item_id, date)
);`
_, err = sqldb.db.Exec(createTable)
if err != nil {
return err
}
return nil
}
func (sqldb SQLLiteDatabase) AddItem(item domain.DBItem) error {
query := `
INSERT INTO item (id, name, class_id, game_id)
VALUES (?, ?, ?, ?)
`
_, err := sqldb.db.Exec(query,
item.ID,
item.Name,
item.ClassID,
item.GameID,
)
if err != nil {
return err
}
return nil
}
func (sqldb SQLLiteDatabase) AddItemHistory(dbItemHistory domain.DBItemHistory) error {
query := `
INSERT INTO item_history (item_id, price, count, date)
VALUES (?, ?, ?, ?)
`
_, err := sqldb.db.Exec(query,
dbItemHistory.ItemID,
dbItemHistory.Price,
dbItemHistory.Count,
dbItemHistory.Date,
)
if err != nil {
return err
}
return nil
}
func (sqldb SQLLiteDatabase) GetItemByClassID(classID string) (*domain.SteamItem, error) {
query := `
SELECT
id,
name,
class_id
FROM item
WHERE class_id = ?
`
row := sqldb.db.QueryRow(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 (sqldb SQLLiteDatabase) GetItemPriceHistoryByID(itemID uuid.UUID, limit int, offset int) ([]domain.ItemPriceHistory, error) {
query := `
SELECT
price,
count,
date
FROM item_history
WHERE item_id = ?
ORDER BY date DESC
LIMIT ?
OFFSET ?
`
var itemPriceHistory []domain.ItemPriceHistory
rows, err := sqldb.db.Query(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 (sqldb SQLLiteDatabase) GetItemsWithLastPriceByName(name string) ([]ItemWithLastPrice, error) {
query := `
SELECT
item.name,
price,
last_date
FROM item
JOIN (
SELECT
item_id,
price,
max(date) as last_date
FROM item_history
GROUP BY item_id
) as last_prices
ON item.id = last_prices.item_id
WHERE item.name like ?
ORDER BY last_date DESC
`
rows, err := sqldb.db.Query(query,
"%"+name+"%",
)
if err != nil {
return nil, err
}
var itemsWithLastPrice []ItemWithLastPrice
var itemWithLastPrice ItemWithLastPrice
var lastDateStr string
layout := "2006-01-02 15:04:05.999999999-07:00"
for rows.Next() {
err := rows.Scan(
&itemWithLastPrice.Name,
&itemWithLastPrice.Price,
&lastDateStr,
)
if err != nil {
fmt.Println("error while scaning row", err)
continue
}
lastDate, err := time.Parse(layout, lastDateStr)
if err != nil {
fmt.Println("error while parsing date", err)
continue
}
itemWithLastPrice.Date = lastDate
itemsWithLastPrice = append(itemsWithLastPrice, itemWithLastPrice)
}
return itemsWithLastPrice, nil
}