lfs.go

  1package database
  2
  3import (
  4	"context"
  5	"strings"
  6
  7	"github.com/charmbracelet/soft-serve/pkg/db"
  8	"github.com/charmbracelet/soft-serve/pkg/db/models"
  9	"github.com/charmbracelet/soft-serve/pkg/store"
 10)
 11
 12type lfsStore struct{}
 13
 14var _ store.LFSStore = (*lfsStore)(nil)
 15
 16func sanitizePath(path string) string {
 17	path = strings.TrimSpace(path)
 18	path = strings.TrimPrefix(path, "/")
 19	return path
 20}
 21
 22// CreateLFSLockForUser implements store.LFSStore.
 23func (*lfsStore) CreateLFSLockForUser(ctx context.Context, tx db.Handler, repoID int64, userID int64, path string, refname string) error {
 24	path = sanitizePath(path)
 25	query := tx.Rebind(`INSERT INTO lfs_locks (repo_id, user_id, path, refname, updated_at)
 26		VALUES (
 27			?,
 28			?,
 29			?,
 30			?,
 31			CURRENT_TIMESTAMP
 32		);
 33	`)
 34	_, err := tx.ExecContext(ctx, query, repoID, userID, path, refname)
 35	return db.WrapError(err) //nolint:wrapcheck
 36}
 37
 38// GetLFSLocks implements store.LFSStore.
 39func (*lfsStore) GetLFSLocks(ctx context.Context, tx db.Handler, repoID int64, page int, limit int) ([]models.LFSLock, error) {
 40	if page <= 0 {
 41		page = 1
 42	}
 43
 44	var locks []models.LFSLock
 45	query := tx.Rebind(`
 46		SELECT *
 47		FROM lfs_locks
 48		WHERE repo_id = ?
 49		ORDER BY updated_at DESC
 50		LIMIT ? OFFSET ?;
 51	`)
 52	err := tx.SelectContext(ctx, &locks, query, repoID, limit, (page-1)*limit)
 53	return locks, db.WrapError(err) //nolint:wrapcheck
 54}
 55
 56func (s *lfsStore) GetLFSLocksWithCount(ctx context.Context, tx db.Handler, repoID int64, page int, limit int) ([]models.LFSLock, int64, error) {
 57	locks, err := s.GetLFSLocks(ctx, tx, repoID, page, limit)
 58	if err != nil {
 59		return nil, 0, err
 60	}
 61
 62	var count int64
 63	query := tx.Rebind(`
 64		SELECT COUNT(*)
 65		FROM lfs_locks
 66		WHERE repo_id = ?;
 67	`)
 68	err = tx.GetContext(ctx, &count, query, repoID)
 69	if err != nil {
 70		return nil, 0, db.WrapError(err) //nolint:wrapcheck
 71	}
 72
 73	return locks, count, nil
 74}
 75
 76// GetLFSLocksForUser implements store.LFSStore.
 77func (*lfsStore) GetLFSLocksForUser(ctx context.Context, tx db.Handler, repoID int64, userID int64) ([]models.LFSLock, error) {
 78	var locks []models.LFSLock
 79	query := tx.Rebind(`
 80		SELECT *
 81		FROM lfs_locks
 82		WHERE repo_id = ? AND user_id = ?;
 83	`)
 84	err := tx.SelectContext(ctx, &locks, query, repoID, userID)
 85	return locks, db.WrapError(err) //nolint:wrapcheck
 86}
 87
 88// GetLFSLocksForPath implements store.LFSStore.
 89func (*lfsStore) GetLFSLockForPath(ctx context.Context, tx db.Handler, repoID int64, path string) (models.LFSLock, error) {
 90	path = sanitizePath(path)
 91	var lock models.LFSLock
 92	query := tx.Rebind(`
 93		SELECT *
 94		FROM lfs_locks
 95		WHERE repo_id = ? AND path = ?;
 96	`)
 97	err := tx.GetContext(ctx, &lock, query, repoID, path)
 98	return lock, db.WrapError(err) //nolint:wrapcheck
 99}
100
101// GetLFSLockForUserPath implements store.LFSStore.
102func (*lfsStore) GetLFSLockForUserPath(ctx context.Context, tx db.Handler, repoID int64, userID int64, path string) (models.LFSLock, error) {
103	path = sanitizePath(path)
104	var lock models.LFSLock
105	query := tx.Rebind(`
106		SELECT *
107		FROM lfs_locks
108		WHERE repo_id = ? AND user_id = ? AND path = ?;
109	`)
110	err := tx.GetContext(ctx, &lock, query, repoID, userID, path)
111	return lock, db.WrapError(err) //nolint:wrapcheck
112}
113
114// GetLFSLockByID implements store.LFSStore.
115func (*lfsStore) GetLFSLockByID(ctx context.Context, tx db.Handler, id int64) (models.LFSLock, error) {
116	var lock models.LFSLock
117	query := tx.Rebind(`
118		SELECT *
119		FROM lfs_locks
120		WHERE lfs_locks.id = ?;
121	`)
122	err := tx.GetContext(ctx, &lock, query, id)
123	return lock, db.WrapError(err) //nolint:wrapcheck
124}
125
126// GetLFSLockForUserByID implements store.LFSStore.
127func (*lfsStore) GetLFSLockForUserByID(ctx context.Context, tx db.Handler, repoID int64, userID int64, id int64) (models.LFSLock, error) {
128	var lock models.LFSLock
129	query := tx.Rebind(`
130		SELECT *
131		FROM lfs_locks
132		WHERE id = ? AND user_id = ? AND repo_id = ?;
133	`)
134	err := tx.GetContext(ctx, &lock, query, id, userID, repoID)
135	return lock, db.WrapError(err) //nolint:wrapcheck
136}
137
138// DeleteLFSLockForUserByID implements store.LFSStore.
139func (*lfsStore) DeleteLFSLockForUserByID(ctx context.Context, tx db.Handler, repoID int64, userID int64, id int64) error {
140	query := tx.Rebind(`
141		DELETE FROM lfs_locks
142		WHERE repo_id = ? AND user_id = ? AND id = ?;
143	`)
144	_, err := tx.ExecContext(ctx, query, repoID, userID, id)
145	return db.WrapError(err) //nolint:wrapcheck
146}
147
148// DeleteLFSLock implements store.LFSStore.
149func (*lfsStore) DeleteLFSLock(ctx context.Context, tx db.Handler, repoID int64, id int64) error {
150	query := tx.Rebind(`
151		DELETE FROM lfs_locks
152		WHERE repo_id = ? AND id = ?;
153	`)
154	_, err := tx.ExecContext(ctx, query, repoID, id)
155	return db.WrapError(err) //nolint:wrapcheck
156}
157
158// CreateLFSObject implements store.LFSStore.
159func (*lfsStore) CreateLFSObject(ctx context.Context, tx db.Handler, repoID int64, oid string, size int64) error {
160	query := tx.Rebind(`INSERT INTO lfs_objects (repo_id, oid, size, updated_at) VALUES (?, ?, ?, CURRENT_TIMESTAMP);`)
161	_, err := tx.ExecContext(ctx, query, repoID, oid, size)
162	return db.WrapError(err) //nolint:wrapcheck
163}
164
165// DeleteLFSObjectByOid implements store.LFSStore.
166func (*lfsStore) DeleteLFSObjectByOid(ctx context.Context, tx db.Handler, repoID int64, oid string) error {
167	query := tx.Rebind(`DELETE FROM lfs_objects WHERE repo_id = ? AND oid = ?;`)
168	_, err := tx.ExecContext(ctx, query, repoID, oid)
169	return db.WrapError(err) //nolint:wrapcheck
170}
171
172// GetLFSObjectByOid implements store.LFSStore.
173func (*lfsStore) GetLFSObjectByOid(ctx context.Context, tx db.Handler, repoID int64, oid string) (models.LFSObject, error) {
174	var obj models.LFSObject
175	query := tx.Rebind(`SELECT * FROM lfs_objects WHERE repo_id = ? AND oid = ?;`)
176	err := tx.GetContext(ctx, &obj, query, repoID, oid)
177	return obj, db.WrapError(err) //nolint:wrapcheck
178}
179
180// GetLFSObjects implements store.LFSStore.
181func (*lfsStore) GetLFSObjects(ctx context.Context, tx db.Handler, repoID int64) ([]models.LFSObject, error) {
182	var objs []models.LFSObject
183	query := tx.Rebind(`SELECT * FROM lfs_objects WHERE repo_id = ?;`)
184	err := tx.SelectContext(ctx, &objs, query, repoID)
185	return objs, db.WrapError(err) //nolint:wrapcheck
186}
187
188// GetLFSObjectsByName implements store.LFSStore.
189func (*lfsStore) GetLFSObjectsByName(ctx context.Context, tx db.Handler, name string) ([]models.LFSObject, error) {
190	var objs []models.LFSObject
191	query := tx.Rebind(`
192		SELECT lfs_objects.*
193		FROM lfs_objects
194		INNER JOIN repos ON lfs_objects.repo_id = repos.id
195		WHERE repos.name = ?;
196	`)
197	err := tx.SelectContext(ctx, &objs, query, name)
198	return objs, db.WrapError(err) //nolint:wrapcheck
199}