157 lines
2.8 KiB
Go
157 lines
2.8 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"os"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/marcopiovanello/yt-dlp-web-ui/v3/server/archive/data"
|
|
"github.com/marcopiovanello/yt-dlp-web-ui/v3/server/archive/domain"
|
|
)
|
|
|
|
type Repository struct {
|
|
db *sql.DB
|
|
}
|
|
|
|
func New(db *sql.DB) domain.Repository {
|
|
return &Repository{
|
|
db: db,
|
|
}
|
|
}
|
|
|
|
func (r *Repository) Archive(ctx context.Context, entry *data.ArchiveEntry) error {
|
|
conn, err := r.db.Conn(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer conn.Close()
|
|
|
|
_, err = conn.ExecContext(
|
|
ctx,
|
|
"INSERT INTO archive (id, title, path, thumbnail, source, metadata, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
|
uuid.NewString(),
|
|
entry.Title,
|
|
entry.Path,
|
|
entry.Thumbnail,
|
|
entry.Source,
|
|
entry.Metadata,
|
|
entry.CreatedAt,
|
|
)
|
|
|
|
return err
|
|
}
|
|
|
|
func (r *Repository) SoftDelete(ctx context.Context, id string) (*data.ArchiveEntry, error) {
|
|
conn, err := r.db.Conn(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
defer conn.Close()
|
|
|
|
tx, err := conn.BeginTx(ctx, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer tx.Rollback()
|
|
|
|
var model data.ArchiveEntry
|
|
|
|
row := tx.QueryRowContext(ctx, "SELECT * FROM archive WHERE id = ?", id)
|
|
|
|
if err := row.Scan(
|
|
&model.Id,
|
|
&model.Title,
|
|
&model.Path,
|
|
&model.Thumbnail,
|
|
&model.Source,
|
|
&model.Metadata,
|
|
&model.CreatedAt,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
_, err = tx.ExecContext(ctx, "DELETE FROM archive WHERE id = ?", id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := tx.Commit(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &model, nil
|
|
}
|
|
|
|
func (r *Repository) HardDelete(ctx context.Context, id string) (*data.ArchiveEntry, error) {
|
|
entry, err := r.SoftDelete(ctx, id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := os.Remove(entry.Path); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return entry, nil
|
|
}
|
|
|
|
func (r *Repository) List(ctx context.Context, startRowId int, limit int) (*[]data.ArchiveEntry, error) {
|
|
conn, err := r.db.Conn(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
defer conn.Close()
|
|
|
|
var entries []data.ArchiveEntry
|
|
|
|
// cursor based pagination
|
|
rows, err := conn.QueryContext(ctx, "SELECT rowid, * FROM archive WHERE rowid > ? LIMIT ?", startRowId, limit)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for rows.Next() {
|
|
var rowId int64
|
|
var entry data.ArchiveEntry
|
|
|
|
if err := rows.Scan(
|
|
&rowId,
|
|
&entry.Id,
|
|
&entry.Title,
|
|
&entry.Path,
|
|
&entry.Thumbnail,
|
|
&entry.Source,
|
|
&entry.Metadata,
|
|
&entry.CreatedAt,
|
|
); err != nil {
|
|
return &entries, err
|
|
}
|
|
|
|
entries = append(entries, entry)
|
|
}
|
|
|
|
return &entries, err
|
|
}
|
|
|
|
func (r *Repository) GetCursor(ctx context.Context, id string) (int64, error) {
|
|
conn, err := r.db.Conn(ctx)
|
|
if err != nil {
|
|
return -1, err
|
|
}
|
|
defer conn.Close()
|
|
|
|
row := conn.QueryRowContext(ctx, "SELECT rowid FROM archive WHERE id = ?", id)
|
|
|
|
var rowId int64
|
|
|
|
if err := row.Scan(&rowId); err != nil {
|
|
return -1, err
|
|
}
|
|
|
|
return rowId, nil
|
|
}
|