1package database23import (4 "context"5 "strings"67 "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)1112type lfsStore struct{}1314var _ store.LFSStore = (*lfsStore)(nil)1516func sanitizePath(path string) string {17 path = strings.TrimSpace(path)18 path = strings.TrimPrefix(path, "/")19 return path20}2122// 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_TIMESTAMP32 );33 `)34 _, err := tx.ExecContext(ctx, query, repoID, userID, path, refname)35 return db.WrapError(err)36}3738// 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 = 142 }4344 var locks []models.LFSLock45 query := tx.Rebind(`46 SELECT *47 FROM lfs_locks48 WHERE repo_id = ?49 ORDER BY updated_at DESC50 LIMIT ? OFFSET ?;51 `)52 err := tx.SelectContext(ctx, &locks, query, repoID, limit, (page-1)*limit)53 return locks, db.WrapError(err)54}5556func (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, err60 }6162 var count int6463 query := tx.Rebind(`64 SELECT COUNT(*)65 FROM lfs_locks66 WHERE repo_id = ?;67 `)68 err = tx.GetContext(ctx, &count, query, repoID)69 if err != nil {70 return nil, 0, db.WrapError(err)71 }7273 return locks, count, nil74}7576// GetLFSLocksForUser implements store.LFSStore.77func (*lfsStore) GetLFSLocksForUser(ctx context.Context, tx db.Handler, repoID int64, userID int64) ([]models.LFSLock, error) {78 var locks []models.LFSLock79 query := tx.Rebind(`80 SELECT *81 FROM lfs_locks82 WHERE repo_id = ? AND user_id = ?;83 `)84 err := tx.SelectContext(ctx, &locks, query, repoID, userID)85 return locks, db.WrapError(err)86}8788// 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.LFSLock92 query := tx.Rebind(`93 SELECT *94 FROM lfs_locks95 WHERE repo_id = ? AND path = ?;96 `)97 err := tx.GetContext(ctx, &lock, query, repoID, path)98 return lock, db.WrapError(err)99}100101// 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.LFSLock105 query := tx.Rebind(`106 SELECT *107 FROM lfs_locks108 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)112}113114// GetLFSLockByID implements store.LFSStore.115func (*lfsStore) GetLFSLockByID(ctx context.Context, tx db.Handler, id int64) (models.LFSLock, error) {116 var lock models.LFSLock117 query := tx.Rebind(`118 SELECT *119 FROM lfs_locks120 WHERE lfs_locks.id = ?;121 `)122 err := tx.GetContext(ctx, &lock, query, id)123 return lock, db.WrapError(err)124}125126// 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.LFSLock129 query := tx.Rebind(`130 SELECT *131 FROM lfs_locks132 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)136}137138// 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_locks142 WHERE repo_id = ? AND user_id = ? AND id = ?;143 `)144 _, err := tx.ExecContext(ctx, query, repoID, userID, id)145 return db.WrapError(err)146}147148// 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_locks152 WHERE repo_id = ? AND id = ?;153 `)154 _, err := tx.ExecContext(ctx, query, repoID, id)155 return db.WrapError(err)156}157158// 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)163}164165// 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)170}171172// GetLFSObjectByOid implements store.LFSStore.173func (*lfsStore) GetLFSObjectByOid(ctx context.Context, tx db.Handler, repoID int64, oid string) (models.LFSObject, error) {174 var obj models.LFSObject175 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)178}179180// GetLFSObjects implements store.LFSStore.181func (*lfsStore) GetLFSObjects(ctx context.Context, tx db.Handler, repoID int64) ([]models.LFSObject, error) {182 var objs []models.LFSObject183 query := tx.Rebind(`SELECT * FROM lfs_objects WHERE repo_id = ?;`)184 err := tx.SelectContext(ctx, &objs, query, repoID)185 return objs, db.WrapError(err)186}187188// GetLFSObjectsByName implements store.LFSStore.189func (*lfsStore) GetLFSObjectsByName(ctx context.Context, tx db.Handler, name string) ([]models.LFSObject, error) {190 var objs []models.LFSObject191 query := tx.Rebind(`192 SELECT lfs_objects.*193 FROM lfs_objects194 INNER JOIN repos ON lfs_objects.repo_id = repos.id195 WHERE repos.name = ?;196 `)197 err := tx.SelectContext(ctx, &objs, query, name)198 return objs, db.WrapError(err)199}