ikurotime / gitgud

public
main / internal/infra/persistence/sqlite/repo_repo.go
2.7 KB · Go Raw
 1package sqlite
 2
 3import (
 4	"context"
 5	"database/sql"
 6	"errors"
 7
 8	"gitgud/internal/domain"
 9)
10
11type RepoRepo struct {
12	db *sql.DB
13}
14
15func NewRepoRepo(db *sql.DB) *RepoRepo {
16	return &RepoRepo{db: db}
17}
18
19func (r *RepoRepo) Create(ctx context.Context, repo *domain.Repository) error {
20	res, err := r.db.ExecContext(ctx,
21		`INSERT INTO repositories(owner_id,name,description,is_private,default_branch) VALUES(?,?,?,?,?)`,
22		repo.OwnerID, repo.Name, repo.Description, repo.IsPrivate, repo.DefaultBranch)
23	if err != nil {
24		if isUniqueViolation(err) {
25			return domain.ErrConflict
26		}
27		return err
28	}
29	repo.ID, _ = res.LastInsertId()
30	return nil
31}
32
33func (r *RepoRepo) Delete(ctx context.Context, id int64) error {
34	_, err := r.db.ExecContext(ctx, `DELETE FROM repositories WHERE id = ?`, id)
35	return err
36}
37
38func (r *RepoRepo) ByOwnerAndName(ctx context.Context, owner, name string) (*domain.Repository, error) {
39	const q = `SELECT r.id, r.owner_id, u.username, r.name, r.description, r.is_private, r.default_branch, r.created_at
40FROM repositories r
41JOIN users u ON u.id = r.owner_id
42WHERE u.username = ? AND r.name = ?`
43
44	var repo domain.Repository
45	err := r.db.QueryRowContext(ctx, q, owner, name).Scan(
46		&repo.ID, &repo.OwnerID, &repo.OwnerName, &repo.Name, &repo.Description,
47		&repo.IsPrivate, &repo.DefaultBranch, &repo.CreatedAt)
48	if err != nil {
49		if errors.Is(err, sql.ErrNoRows) {
50			return nil, domain.ErrNotFound
51		}
52		return nil, err
53	}
54	return &repo, nil
55}
56
57func (r *RepoRepo) ListByOwner(ctx context.Context, ownerID int64) ([]*domain.Repository, error) {
58	const q = `SELECT r.id, r.owner_id, u.username, r.name, r.description, r.is_private, r.default_branch, r.created_at
59FROM repositories r
60JOIN users u ON u.id = r.owner_id
61WHERE r.owner_id = ?
62ORDER BY r.created_at DESC, r.id DESC`
63
64	return r.queryRepos(ctx, q, ownerID)
65}
66
67func (r *RepoRepo) ListPublic(ctx context.Context) ([]*domain.Repository, error) {
68	const q = `SELECT r.id, r.owner_id, u.username, r.name, r.description, r.is_private, r.default_branch, r.created_at
69FROM repositories r
70JOIN users u ON u.id = r.owner_id
71WHERE r.is_private = 0
72ORDER BY r.created_at DESC, r.id DESC`
73
74	return r.queryRepos(ctx, q)
75}
76
77func (r *RepoRepo) queryRepos(ctx context.Context, q string, args ...any) ([]*domain.Repository, error) {
78	rows, err := r.db.QueryContext(ctx, q, args...)
79	if err != nil {
80		return nil, err
81	}
82	defer rows.Close()
83
84	var repos []*domain.Repository
85	for rows.Next() {
86		var repo domain.Repository
87		if err := rows.Scan(
88			&repo.ID, &repo.OwnerID, &repo.OwnerName, &repo.Name, &repo.Description,
89			&repo.IsPrivate, &repo.DefaultBranch, &repo.CreatedAt); err != nil {
90			return nil, err
91		}
92		repos = append(repos, &repo)
93	}
94	return repos, rows.Err()
95}