Function bodies 254 total
ReorderIssues method · go · L270-L282 (13 LOC)backend/internal/storage/postgres/repo.go
func (r *issueRepo) ReorderIssues(ctx context.Context, issueIDs []string) error {
tx, err := r.db.BeginTx(ctx, nil)
if err != nil {
return fmt.Errorf("postgres: begin: %w", err)
}
defer tx.Rollback()
for pos, id := range issueIDs {
if _, err := tx.ExecContext(ctx, `UPDATE issues SET position=$1 WHERE id=$2`, pos, id); err != nil {
return fmt.Errorf("postgres: reorder issue: %w", err)
}
}
return tx.Commit()
}GetDayStats method · go · L284-L310 (27 LOC)backend/internal/storage/postgres/repo.go
func (r *issueRepo) GetDayStats(ctx context.Context, day time.Time) (storage.DayStats, error) {
start := time.Date(day.Year(), day.Month(), day.Day(), 0, 0, 0, 0, time.UTC)
end := start.AddDate(0, 0, 1)
qBy := func(column string) ([]domain.Issue, error) {
rows, err := r.db.QueryContext(ctx, selectIssueCols+
fmt.Sprintf(` WHERE %s IS NOT NULL AND %s >= $1 AND %s < $2 ORDER BY %s ASC`, column, column, column, column),
start, end)
if err != nil {
return nil, fmt.Errorf("postgres: day stats %s: %w", column, err)
}
defer rows.Close()
return collectIssues(rows)
}
created, err := qBy("created_at")
if err != nil {
return storage.DayStats{}, err
}
approved, err := qBy("approved_at")
if err != nil {
return storage.DayStats{}, err
}
completed, err := qBy("completed_at")
if err != nil {
return storage.DayStats{}, err
}
return storage.DayStats{Created: created, Approved: approved, Completed: completed}, nil
}AddDependency method · go · L312-L320 (9 LOC)backend/internal/storage/postgres/repo.go
func (r *issueRepo) AddDependency(ctx context.Context, blockerID, blockedID string) error {
_, err := r.db.ExecContext(ctx,
`INSERT INTO issue_dependencies (blocker_id, blocked_id) VALUES ($1, $2) ON CONFLICT DO NOTHING`,
blockerID, blockedID)
if err != nil {
return fmt.Errorf("postgres: add dependency: %w", err)
}
return nil
}RemoveDependency method · go · L322-L330 (9 LOC)backend/internal/storage/postgres/repo.go
func (r *issueRepo) RemoveDependency(ctx context.Context, blockerID, blockedID string) error {
_, err := r.db.ExecContext(ctx,
`DELETE FROM issue_dependencies WHERE blocker_id = $1 AND blocked_id = $2`,
blockerID, blockedID)
if err != nil {
return fmt.Errorf("postgres: remove dependency: %w", err)
}
return nil
}GetBlockedBy method · go · L332-L348 (17 LOC)backend/internal/storage/postgres/repo.go
func (r *issueRepo) GetBlockedBy(ctx context.Context, issueID string) ([]string, error) {
rows, err := r.db.QueryContext(ctx,
`SELECT blocker_id FROM issue_dependencies WHERE blocked_id = $1`, issueID)
if err != nil {
return nil, fmt.Errorf("postgres: get blocked by: %w", err)
}
defer rows.Close()
var out []string
for rows.Next() {
var id string
if err := rows.Scan(&id); err != nil {
return nil, err
}
out = append(out, id)
}
return out, rows.Err()
}scanIssue function · go · L356-L395 (40 LOC)backend/internal/storage/postgres/repo.go
func scanIssue(row interface{ Scan(...any) error }) (domain.Issue, error) {
var i domain.Issue
var parent sql.NullString
var propsBytes, criteriaBytes []byte
var approvedAt, completedAt sql.NullTime
err := row.Scan(&i.ID, &i.BoardID, &parent, &i.Title, &i.Body, &i.Instructions, &i.Status, &propsBytes, &criteriaBytes, &i.Position, &i.CreatedAt, &i.UpdatedAt, &approvedAt, &completedAt)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return domain.Issue{}, storage.ErrNotFound
}
return domain.Issue{}, fmt.Errorf("postgres: scan issue: %w", err)
}
if len(propsBytes) > 0 {
_ = json.Unmarshal(propsBytes, &i.Properties)
}
if i.Properties == nil {
i.Properties = map[string]any{}
}
if len(criteriaBytes) > 0 {
_ = json.Unmarshal(criteriaBytes, &i.Criteria)
}
if i.Criteria == nil {
i.Criteria = []domain.Criterion{}
}
if parent.Valid {
p := parent.String
i.ParentID = &p
}
if approvedAt.Valid {
t := approvedAt.Time.UTC()
i.ApprovedAt = &t
}
if completecollectIssues function · go · L397-L407 (11 LOC)backend/internal/storage/postgres/repo.go
func collectIssues(rows *sql.Rows) ([]domain.Issue, error) {
var out []domain.Issue
for rows.Next() {
i, err := scanIssue(rows)
if err != nil {
return nil, err
}
out = append(out, i)
}
return out, rows.Err()
}Open data scored by Repobility · https://repobility.com
utcPtr function · go · L409-L415 (7 LOC)backend/internal/storage/postgres/repo.go
func utcPtr(t *time.Time) any {
if t == nil {
return nil
}
u := t.UTC()
return u
}detectCycleTx function · go · L417-L434 (18 LOC)backend/internal/storage/postgres/repo.go
func detectCycleTx(ctx context.Context, tx *sql.Tx, self, target string) (bool, error) {
q := `
WITH RECURSIVE ancestors(id) AS (
SELECT parent_id FROM issues WHERE id = $1
UNION ALL
SELECT i.parent_id FROM issues i JOIN ancestors a ON i.id = a.id WHERE i.parent_id IS NOT NULL
)
SELECT 1 FROM ancestors WHERE id = $2 LIMIT 1`
var hit int
err := tx.QueryRowContext(ctx, q, target, self).Scan(&hit)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return false, nil
}
return false, fmt.Errorf("postgres: cycle detect: %w", err)
}
return hit == 1, nil
}Create method · go · L442-L450 (9 LOC)backend/internal/storage/postgres/repo.go
func (r *boardRepo) Create(ctx context.Context, b domain.Board) (domain.Board, error) {
_, err := r.db.ExecContext(ctx,
`INSERT INTO boards (id, name, view_type, created_at) VALUES ($1,$2,$3,$4)`,
b.ID, b.Name, b.ViewType, b.CreatedAt.UTC())
if err != nil {
return domain.Board{}, fmt.Errorf("postgres: create board: %w", err)
}
return b, nil
}GetByID method · go · L452-L465 (14 LOC)backend/internal/storage/postgres/repo.go
func (r *boardRepo) GetByID(ctx context.Context, id string) (domain.Board, error) {
var b domain.Board
err := r.db.QueryRowContext(ctx,
`SELECT id, name, view_type, created_at FROM boards WHERE id = $1`, id).
Scan(&b.ID, &b.Name, &b.ViewType, &b.CreatedAt)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return domain.Board{}, storage.ErrNotFound
}
return domain.Board{}, fmt.Errorf("postgres: get board: %w", err)
}
b.CreatedAt = b.CreatedAt.UTC()
return b, nil
}List method · go · L467-L484 (18 LOC)backend/internal/storage/postgres/repo.go
func (r *boardRepo) List(ctx context.Context) ([]domain.Board, error) {
rows, err := r.db.QueryContext(ctx,
`SELECT id, name, view_type, created_at FROM boards ORDER BY created_at ASC`)
if err != nil {
return nil, fmt.Errorf("postgres: list boards: %w", err)
}
defer rows.Close()
var out []domain.Board
for rows.Next() {
var b domain.Board
if err := rows.Scan(&b.ID, &b.Name, &b.ViewType, &b.CreatedAt); err != nil {
return nil, err
}
b.CreatedAt = b.CreatedAt.UTC()
out = append(out, b)
}
return out, rows.Err()
}Update method · go · L486-L504 (19 LOC)backend/internal/storage/postgres/repo.go
func (r *boardRepo) Update(ctx context.Context, id string, name *string, viewType *domain.ViewType) (domain.Board, error) {
cur, err := r.GetByID(ctx, id)
if err != nil {
return domain.Board{}, err
}
if name != nil {
cur.Name = *name
}
if viewType != nil {
cur.ViewType = *viewType
}
_, err = r.db.ExecContext(ctx,
`UPDATE boards SET name=$1, view_type=$2 WHERE id=$3`,
cur.Name, cur.ViewType, id)
if err != nil {
return domain.Board{}, fmt.Errorf("postgres: update board: %w", err)
}
return cur, nil
}Delete method · go · L506-L516 (11 LOC)backend/internal/storage/postgres/repo.go
func (r *boardRepo) Delete(ctx context.Context, id string) error {
res, err := r.db.ExecContext(ctx, `DELETE FROM boards WHERE id = $1`, id)
if err != nil {
return fmt.Errorf("postgres: delete board: %w", err)
}
n, _ := res.RowsAffected()
if n == 0 {
return storage.ErrNotFound
}
return nil
}Create method · go · L19-L33 (15 LOC)backend/internal/storage/sqlite/comment_repo.go
func (r *commentRepo) Create(ctx context.Context, issueID, body string) (*domain.Comment, error) {
c := &domain.Comment{
ID: uuid.NewString(),
IssueID: issueID,
Body: body,
CreatedAt: time.Now().UTC(),
}
_, err := r.db.ExecContext(ctx,
`INSERT INTO comments (id, issue_id, body, created_at) VALUES (?, ?, ?, ?)`,
c.ID, c.IssueID, c.Body, c.CreatedAt)
if err != nil {
return nil, fmt.Errorf("sqlite: create comment: %w", err)
}
return c, nil
}Methodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
List method · go · L35-L53 (19 LOC)backend/internal/storage/sqlite/comment_repo.go
func (r *commentRepo) List(ctx context.Context, issueID string) ([]domain.Comment, error) {
rows, err := r.db.QueryContext(ctx,
`SELECT id, issue_id, body, created_at FROM comments WHERE issue_id = ? ORDER BY created_at ASC`,
issueID)
if err != nil {
return nil, fmt.Errorf("sqlite: list comments: %w", err)
}
defer rows.Close()
var out []domain.Comment
for rows.Next() {
var c domain.Comment
if err := rows.Scan(&c.ID, &c.IssueID, &c.Body, &c.CreatedAt); err != nil {
return nil, fmt.Errorf("sqlite: scan comment: %w", err)
}
c.CreatedAt = c.CreatedAt.UTC()
out = append(out, c)
}
return out, rows.Err()
}Delete method · go · L55-L65 (11 LOC)backend/internal/storage/sqlite/comment_repo.go
func (r *commentRepo) Delete(ctx context.Context, commentID string) error {
res, err := r.db.ExecContext(ctx, `DELETE FROM comments WHERE id = ?`, commentID)
if err != nil {
return fmt.Errorf("sqlite: delete comment: %w", err)
}
n, _ := res.RowsAffected()
if n == 0 {
return storage.ErrNotFound
}
return nil
}runMigrations function · go · L14-L23 (10 LOC)backend/internal/storage/sqlite/migrations.go
func runMigrations(db *sql.DB) error {
goose.SetBaseFS(migrationsFS)
if err := goose.SetDialect("sqlite3"); err != nil {
return fmt.Errorf("sqlite: set dialect: %w", err)
}
if err := goose.Up(db, "migrations"); err != nil {
return fmt.Errorf("sqlite: goose up: %w", err)
}
return nil
}Create method · go · L20-L35 (16 LOC)backend/internal/storage/sqlite/property_repo.go
func (r *boardPropertyRepo) Create(ctx context.Context, p domain.BoardProperty) (domain.BoardProperty, error) {
if p.ID == "" {
p.ID = uuid.NewString()
}
if p.CreatedAt.IsZero() {
p.CreatedAt = time.Now().UTC()
}
opts, _ := json.Marshal(p.Options)
_, err := r.db.ExecContext(ctx,
`INSERT INTO board_properties (id, board_id, name, type, options, position, created_at) VALUES (?,?,?,?,?,?,?)`,
p.ID, p.BoardID, p.Name, p.Type, string(opts), p.Position, p.CreatedAt.UTC())
if err != nil {
return domain.BoardProperty{}, fmt.Errorf("sqlite: create board_property: %w", err)
}
return p, nil
}List method · go · L37-L59 (23 LOC)backend/internal/storage/sqlite/property_repo.go
func (r *boardPropertyRepo) List(ctx context.Context, boardID string) ([]domain.BoardProperty, error) {
rows, err := r.db.QueryContext(ctx,
`SELECT id, board_id, name, type, options, position, created_at FROM board_properties WHERE board_id = ? ORDER BY position ASC`, boardID)
if err != nil {
return nil, fmt.Errorf("sqlite: list board_properties: %w", err)
}
defer rows.Close()
var out []domain.BoardProperty
for rows.Next() {
var p domain.BoardProperty
var opts string
if err := rows.Scan(&p.ID, &p.BoardID, &p.Name, &p.Type, &opts, &p.Position, &p.CreatedAt); err != nil {
return nil, err
}
_ = json.Unmarshal([]byte(opts), &p.Options)
if p.Options == nil {
p.Options = []string{}
}
p.CreatedAt = p.CreatedAt.UTC()
out = append(out, p)
}
return out, rows.Err()
}Update method · go · L61-L93 (33 LOC)backend/internal/storage/sqlite/property_repo.go
func (r *boardPropertyRepo) Update(ctx context.Context, id string, name *string, options *[]string, position *int) (domain.BoardProperty, error) {
// Get current
var p domain.BoardProperty
var opts string
err := r.db.QueryRowContext(ctx,
`SELECT id, board_id, name, type, options, position, created_at FROM board_properties WHERE id = ?`, id).
Scan(&p.ID, &p.BoardID, &p.Name, &p.Type, &opts, &p.Position, &p.CreatedAt)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return domain.BoardProperty{}, storage.ErrNotFound
}
return domain.BoardProperty{}, err
}
_ = json.Unmarshal([]byte(opts), &p.Options)
if name != nil {
p.Name = *name
}
if options != nil {
p.Options = *options
}
if position != nil {
p.Position = *position
}
newOpts, _ := json.Marshal(p.Options)
_, err = r.db.ExecContext(ctx,
`UPDATE board_properties SET name=?, options=?, position=? WHERE id=?`,
p.Name, string(newOpts), p.Position, id)
if err != nil {
return domain.BoardProperty{}, Delete method · go · L95-L105 (11 LOC)backend/internal/storage/sqlite/property_repo.go
func (r *boardPropertyRepo) Delete(ctx context.Context, id string) error {
res, err := r.db.ExecContext(ctx, `DELETE FROM board_properties WHERE id = ?`, id)
if err != nil {
return fmt.Errorf("sqlite: delete board_property: %w", err)
}
n, _ := res.RowsAffected()
if n == 0 {
return storage.ErrNotFound
}
return nil
}Open function · go · L29-L50 (22 LOC)backend/internal/storage/sqlite/repo.go
func Open(dsn string) (*Repo, error) {
db, err := sql.Open("sqlite", dsn+"?_pragma=foreign_keys(1)&_pragma=journal_mode(WAL)")
if err != nil {
return nil, fmt.Errorf("sqlite open: %w", err)
}
if err := db.Ping(); err != nil {
_ = db.Close()
return nil, fmt.Errorf("sqlite ping: %w", err)
}
if err := runMigrations(db); err != nil {
_ = db.Close()
return nil, err
}
return &Repo{
db: db,
issues: &issueRepo{db: db},
boards: &boardRepo{db: db},
props: &boardPropertyRepo{db: db},
webhooks: &webhookRepo{db: db},
comments: &commentRepo{db: db},
}, nil
}Want this analysis on your repo? https://repobility.com/scan/
Create method · go · L65-L83 (19 LOC)backend/internal/storage/sqlite/repo.go
func (r *issueRepo) Create(ctx context.Context, i domain.Issue) (domain.Issue, error) {
if i.Properties == nil {
i.Properties = map[string]any{}
}
if i.Criteria == nil {
i.Criteria = []domain.Criterion{}
}
propsJSON, _ := json.Marshal(i.Properties)
criteriaJSON, _ := json.Marshal(i.Criteria)
_, err := r.db.ExecContext(ctx, `
INSERT INTO issues (id, board_id, parent_id, title, body, instructions, status, properties, criteria, position, created_at, updated_at, approved_at, completed_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
i.ID, i.BoardID, i.ParentID, i.Title, i.Body, i.Instructions, i.Status, string(propsJSON), string(criteriaJSON), i.Position,
i.CreatedAt.UTC(), i.UpdatedAt.UTC(), utcPtr(i.ApprovedAt), utcPtr(i.CompletedAt))
if err != nil {
return domain.Issue{}, fmt.Errorf("sqlite: create issue: %w", err)
}
return i, nil
}GetByID method · go · L85-L88 (4 LOC)backend/internal/storage/sqlite/repo.go
func (r *issueRepo) GetByID(ctx context.Context, id string) (domain.Issue, error) {
row := r.db.QueryRowContext(ctx, selectIssueCols+` WHERE id = ?`, id)
return scanIssue(row)
}ListChildren method · go · L90-L97 (8 LOC)backend/internal/storage/sqlite/repo.go
func (r *issueRepo) ListChildren(ctx context.Context, parentID string) ([]domain.Issue, error) {
rows, err := r.db.QueryContext(ctx, selectIssueCols+` WHERE parent_id = ? ORDER BY created_at ASC`, parentID)
if err != nil {
return nil, fmt.Errorf("sqlite: list children: %w", err)
}
defer rows.Close()
return collectIssues(rows)
}List method · go · L99-L125 (27 LOC)backend/internal/storage/sqlite/repo.go
func (r *issueRepo) List(ctx context.Context, f storage.IssueFilter) ([]domain.Issue, error) {
q := selectIssueCols + ` WHERE 1=1`
var args []any
if f.BoardID != nil {
q += ` AND board_id = ?`
args = append(args, *f.BoardID)
}
if f.Status != nil {
q += ` AND status = ?`
args = append(args, string(*f.Status))
}
if f.ParentID != nil {
if *f.ParentID == "" {
q += ` AND parent_id IS NULL`
} else {
q += ` AND parent_id = ?`
args = append(args, *f.ParentID)
}
}
q += ` ORDER BY position ASC, created_at DESC`
rows, err := r.db.QueryContext(ctx, q, args...)
if err != nil {
return nil, fmt.Errorf("sqlite: list issues: %w", err)
}
defer rows.Close()
return collectIssues(rows)
}Update method · go · L127-L191 (65 LOC)backend/internal/storage/sqlite/repo.go
func (r *issueRepo) Update(ctx context.Context, id string, p storage.IssuePatch) (domain.Issue, error) {
tx, err := r.db.BeginTx(ctx, nil)
if err != nil {
return domain.Issue{}, fmt.Errorf("sqlite: begin: %w", err)
}
defer tx.Rollback()
cur, err := scanIssue(tx.QueryRowContext(ctx, selectIssueCols+` WHERE id = ?`, id))
if err != nil {
return domain.Issue{}, err
}
if p.Title != nil {
cur.Title = *p.Title
}
if p.Body != nil {
cur.Body = *p.Body
}
if p.Status != nil {
cur.Status = *p.Status
}
if p.Properties != nil {
cur.Properties = *p.Properties
}
if p.Instructions != nil {
cur.Instructions = *p.Instructions
}
if p.Criteria != nil {
cur.Criteria = *p.Criteria
}
if p.ParentID != nil {
newParent := *p.ParentID
if newParent != nil {
if *newParent == id {
return domain.Issue{}, storage.ErrCycle
}
// Recursive CTE로 순환 탐지
hasCycle, err := detectCycleTx(ctx, tx, id, *newParent)
if err != nil {
return domain.Issue{}, err
}
iDelete method · go · L193-L203 (11 LOC)backend/internal/storage/sqlite/repo.go
func (r *issueRepo) Delete(ctx context.Context, id string) error {
res, err := r.db.ExecContext(ctx, `DELETE FROM issues WHERE id = ?`, id)
if err != nil {
return fmt.Errorf("sqlite: delete issue: %w", err)
}
n, _ := res.RowsAffected()
if n == 0 {
return storage.ErrNotFound
}
return nil
}Approve method · go · L205-L218 (14 LOC)backend/internal/storage/sqlite/repo.go
func (r *issueRepo) Approve(ctx context.Context, id string, now time.Time) (domain.Issue, error) {
// 멱등: 이미 Approved면 approved_at 유지, 상태만 확정
_, err := r.db.ExecContext(ctx, `
UPDATE issues
SET status='Approved',
approved_at = COALESCE(approved_at, ?),
updated_at = ?
WHERE id = ? AND status IN ('Pending','Approved')`,
now.UTC(), now.UTC(), id)
if err != nil {
return domain.Issue{}, fmt.Errorf("sqlite: approve: %w", err)
}
return r.GetByID(ctx, id)
}Complete method · go · L220-L243 (24 LOC)backend/internal/storage/sqlite/repo.go
func (r *issueRepo) Complete(ctx context.Context, id string, now time.Time) (domain.Issue, error) {
res, err := r.db.ExecContext(ctx, `
UPDATE issues
SET status='Done',
completed_at = COALESCE(completed_at, ?),
updated_at = ?
WHERE id = ? AND status = 'QA'`,
now.UTC(), now.UTC(), id)
if err != nil {
return domain.Issue{}, fmt.Errorf("sqlite: complete: %w", err)
}
n, _ := res.RowsAffected()
if n == 0 {
cur, err := r.GetByID(ctx, id)
if err != nil {
return domain.Issue{}, err
}
if cur.Status == domain.StatusDone {
return cur, nil // 멱등
}
return domain.Issue{}, storage.ErrConflict
}
return r.GetByID(ctx, id)
}Repobility · open methodology · https://repobility.com/research/
GetMonthStats method · go · L245-L284 (40 LOC)backend/internal/storage/sqlite/repo.go
func (r *issueRepo) GetMonthStats(ctx context.Context, year int, month time.Month) ([]storage.DayCount, error) {
start := time.Date(year, month, 1, 0, 0, 0, 0, time.UTC)
end := start.AddDate(0, 1, 0)
q := `
WITH days AS (
SELECT substr(created_at, 1, 10) AS d, 1 AS c, 0 AS a, 0 AS f FROM issues
WHERE created_at >= ? AND created_at < ?
UNION ALL
SELECT substr(approved_at, 1, 10) AS d, 0, 1, 0 FROM issues
WHERE approved_at IS NOT NULL AND approved_at >= ? AND approved_at < ?
UNION ALL
SELECT substr(completed_at, 1, 10) AS d, 0, 0, 1 FROM issues
WHERE completed_at IS NOT NULL AND completed_at >= ? AND completed_at < ?
)
SELECT d, SUM(c), SUM(a), SUM(f)
FROM days
GROUP BY d
ORDER BY d`
rows, err := r.db.QueryContext(ctx, q, start, end, start, end, start, end)
if err != nil {
return nil, fmt.Errorf("sqlite: month stats: %w", err)
}
defer rows.Close()
var out []storage.DayCount
for rows.Next() {
var dateStr sql.NullString
var c storage.DayCoGetDayStats method · go · L286-L312 (27 LOC)backend/internal/storage/sqlite/repo.go
func (r *issueRepo) GetDayStats(ctx context.Context, day time.Time) (storage.DayStats, error) {
start := time.Date(day.Year(), day.Month(), day.Day(), 0, 0, 0, 0, time.UTC)
end := start.AddDate(0, 0, 1)
qBy := func(column string) ([]domain.Issue, error) {
rows, err := r.db.QueryContext(ctx, selectIssueCols+
fmt.Sprintf(` WHERE %s IS NOT NULL AND %s >= ? AND %s < ? ORDER BY %s ASC`, column, column, column, column),
start, end)
if err != nil {
return nil, fmt.Errorf("sqlite: day stats %s: %w", column, err)
}
defer rows.Close()
return collectIssues(rows)
}
created, err := qBy("created_at")
if err != nil {
return storage.DayStats{}, err
}
approved, err := qBy("approved_at")
if err != nil {
return storage.DayStats{}, err
}
completed, err := qBy("completed_at")
if err != nil {
return storage.DayStats{}, err
}
return storage.DayStats{Created: created, Approved: approved, Completed: completed}, nil
}ReorderIssues method · go · L314-L326 (13 LOC)backend/internal/storage/sqlite/repo.go
func (r *issueRepo) ReorderIssues(ctx context.Context, issueIDs []string) error {
tx, err := r.db.BeginTx(ctx, nil)
if err != nil {
return fmt.Errorf("sqlite: begin: %w", err)
}
defer tx.Rollback()
for pos, id := range issueIDs {
if _, err := tx.ExecContext(ctx, `UPDATE issues SET position=? WHERE id=?`, pos, id); err != nil {
return fmt.Errorf("sqlite: reorder issue: %w", err)
}
}
return tx.Commit()
}AddDependency method · go · L328-L336 (9 LOC)backend/internal/storage/sqlite/repo.go
func (r *issueRepo) AddDependency(ctx context.Context, blockerID, blockedID string) error {
_, err := r.db.ExecContext(ctx,
`INSERT OR IGNORE INTO issue_dependencies (blocker_id, blocked_id) VALUES (?, ?)`,
blockerID, blockedID)
if err != nil {
return fmt.Errorf("sqlite: add dependency: %w", err)
}
return nil
}RemoveDependency method · go · L338-L346 (9 LOC)backend/internal/storage/sqlite/repo.go
func (r *issueRepo) RemoveDependency(ctx context.Context, blockerID, blockedID string) error {
_, err := r.db.ExecContext(ctx,
`DELETE FROM issue_dependencies WHERE blocker_id = ? AND blocked_id = ?`,
blockerID, blockedID)
if err != nil {
return fmt.Errorf("sqlite: remove dependency: %w", err)
}
return nil
}GetBlockedBy method · go · L348-L364 (17 LOC)backend/internal/storage/sqlite/repo.go
func (r *issueRepo) GetBlockedBy(ctx context.Context, issueID string) ([]string, error) {
rows, err := r.db.QueryContext(ctx,
`SELECT blocker_id FROM issue_dependencies WHERE blocked_id = ?`, issueID)
if err != nil {
return nil, fmt.Errorf("sqlite: get blocked by: %w", err)
}
defer rows.Close()
var out []string
for rows.Next() {
var id string
if err := rows.Scan(&id); err != nil {
return nil, err
}
out = append(out, id)
}
return out, rows.Err()
}scanIssue function · go · L372-L411 (40 LOC)backend/internal/storage/sqlite/repo.go
func scanIssue(row interface{ Scan(...any) error }) (domain.Issue, error) {
var i domain.Issue
var parent sql.NullString
var propsStr, criteriaStr string
var approvedAt, completedAt sql.NullTime
err := row.Scan(&i.ID, &i.BoardID, &parent, &i.Title, &i.Body, &i.Instructions, &i.Status, &propsStr, &criteriaStr, &i.Position, &i.CreatedAt, &i.UpdatedAt, &approvedAt, &completedAt)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return domain.Issue{}, storage.ErrNotFound
}
return domain.Issue{}, fmt.Errorf("sqlite: scan issue: %w", err)
}
if propsStr != "" {
_ = json.Unmarshal([]byte(propsStr), &i.Properties)
}
if criteriaStr != "" {
_ = json.Unmarshal([]byte(criteriaStr), &i.Criteria)
}
if i.Criteria == nil {
i.Criteria = []domain.Criterion{}
}
if i.Properties == nil {
i.Properties = map[string]any{}
}
if parent.Valid {
p := parent.String
i.ParentID = &p
}
if approvedAt.Valid {
t := approvedAt.Time.UTC()
i.ApprovedAt = &t
}
if completedAt.ValicollectIssues function · go · L413-L423 (11 LOC)backend/internal/storage/sqlite/repo.go
func collectIssues(rows *sql.Rows) ([]domain.Issue, error) {
var out []domain.Issue
for rows.Next() {
i, err := scanIssue(rows)
if err != nil {
return nil, err
}
out = append(out, i)
}
return out, rows.Err()
}Open data scored by Repobility · https://repobility.com
utcPtr function · go · L425-L431 (7 LOC)backend/internal/storage/sqlite/repo.go
func utcPtr(t *time.Time) any {
if t == nil {
return nil
}
u := t.UTC()
return u
}detectCycleTx function · go · L434-L451 (18 LOC)backend/internal/storage/sqlite/repo.go
func detectCycleTx(ctx context.Context, tx *sql.Tx, self, target string) (bool, error) {
q := `
WITH RECURSIVE ancestors(id) AS (
SELECT parent_id FROM issues WHERE id = ?
UNION ALL
SELECT i.parent_id FROM issues i JOIN ancestors a ON i.id = a.id WHERE i.parent_id IS NOT NULL
)
SELECT 1 FROM ancestors WHERE id = ? LIMIT 1`
var hit int
err := tx.QueryRowContext(ctx, q, target, self).Scan(&hit)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return false, nil
}
return false, fmt.Errorf("sqlite: cycle detect: %w", err)
}
return hit == 1, nil
}Create method · go · L459-L467 (9 LOC)backend/internal/storage/sqlite/repo.go
func (r *boardRepo) Create(ctx context.Context, b domain.Board) (domain.Board, error) {
_, err := r.db.ExecContext(ctx,
`INSERT INTO boards (id, name, view_type, created_at) VALUES (?, ?, ?, ?)`,
b.ID, b.Name, b.ViewType, b.CreatedAt.UTC())
if err != nil {
return domain.Board{}, fmt.Errorf("sqlite: create board: %w", err)
}
return b, nil
}GetByID method · go · L469-L482 (14 LOC)backend/internal/storage/sqlite/repo.go
func (r *boardRepo) GetByID(ctx context.Context, id string) (domain.Board, error) {
var b domain.Board
err := r.db.QueryRowContext(ctx,
`SELECT id, name, view_type, created_at FROM boards WHERE id = ?`, id).
Scan(&b.ID, &b.Name, &b.ViewType, &b.CreatedAt)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return domain.Board{}, storage.ErrNotFound
}
return domain.Board{}, fmt.Errorf("sqlite: get board: %w", err)
}
b.CreatedAt = b.CreatedAt.UTC()
return b, nil
}List method · go · L484-L501 (18 LOC)backend/internal/storage/sqlite/repo.go
func (r *boardRepo) List(ctx context.Context) ([]domain.Board, error) {
rows, err := r.db.QueryContext(ctx,
`SELECT id, name, view_type, created_at FROM boards ORDER BY created_at ASC`)
if err != nil {
return nil, fmt.Errorf("sqlite: list boards: %w", err)
}
defer rows.Close()
var out []domain.Board
for rows.Next() {
var b domain.Board
if err := rows.Scan(&b.ID, &b.Name, &b.ViewType, &b.CreatedAt); err != nil {
return nil, err
}
b.CreatedAt = b.CreatedAt.UTC()
out = append(out, b)
}
return out, rows.Err()
}Update method · go · L503-L521 (19 LOC)backend/internal/storage/sqlite/repo.go
func (r *boardRepo) Update(ctx context.Context, id string, name *string, viewType *domain.ViewType) (domain.Board, error) {
cur, err := r.GetByID(ctx, id)
if err != nil {
return domain.Board{}, err
}
if name != nil {
cur.Name = *name
}
if viewType != nil {
cur.ViewType = *viewType
}
_, err = r.db.ExecContext(ctx,
`UPDATE boards SET name=?, view_type=? WHERE id=?`,
cur.Name, cur.ViewType, id)
if err != nil {
return domain.Board{}, fmt.Errorf("sqlite: update board: %w", err)
}
return cur, nil
}Delete method · go · L523-L533 (11 LOC)backend/internal/storage/sqlite/repo.go
func (r *boardRepo) Delete(ctx context.Context, id string) error {
res, err := r.db.ExecContext(ctx, `DELETE FROM boards WHERE id = ?`, id)
if err != nil {
return fmt.Errorf("sqlite: delete board: %w", err)
}
n, _ := res.RowsAffected()
if n == 0 {
return storage.ErrNotFound
}
return nil
}Create method · go · L20-L39 (20 LOC)backend/internal/storage/sqlite/webhook_repo.go
func (r *webhookRepo) Create(ctx context.Context, wh domain.Webhook) (domain.Webhook, error) {
if wh.ID == "" {
wh.ID = uuid.NewString()
}
if wh.CreatedAt.IsZero() {
wh.CreatedAt = time.Now().UTC()
}
evts, _ := json.Marshal(wh.Events)
enabled := 0
if wh.Enabled {
enabled = 1
}
_, err := r.db.ExecContext(ctx,
`INSERT INTO webhooks (id, board_id, name, url, events, enabled, created_at) VALUES (?,?,?,?,?,?,?)`,
wh.ID, wh.BoardID, wh.Name, wh.URL, string(evts), enabled, wh.CreatedAt.UTC())
if err != nil {
return domain.Webhook{}, fmt.Errorf("sqlite: create webhook: %w", err)
}
return wh, nil
}Methodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
List method · go · L41-L49 (9 LOC)backend/internal/storage/sqlite/webhook_repo.go
func (r *webhookRepo) List(ctx context.Context, boardID string) ([]domain.Webhook, error) {
rows, err := r.db.QueryContext(ctx,
`SELECT id, board_id, name, url, events, enabled, created_at FROM webhooks WHERE board_id = ? ORDER BY created_at ASC`, boardID)
if err != nil {
return nil, err
}
defer rows.Close()
return scanWebhooks(rows)
}ListByEvent method · go · L51-L69 (19 LOC)backend/internal/storage/sqlite/webhook_repo.go
func (r *webhookRepo) ListByEvent(ctx context.Context, boardID string, event domain.WebhookEvent) ([]domain.Webhook, error) {
all, err := r.List(ctx, boardID)
if err != nil {
return nil, err
}
var out []domain.Webhook
for _, wh := range all {
if !wh.Enabled {
continue
}
for _, e := range wh.Events {
if e == event {
out = append(out, wh)
break
}
}
}
return out, nil
}Update method · go · L71-L100 (30 LOC)backend/internal/storage/sqlite/webhook_repo.go
func (r *webhookRepo) Update(ctx context.Context, id string, name *string, url *string, events *[]domain.WebhookEvent, enabled *bool) (domain.Webhook, error) {
wh, err := r.getByID(ctx, id)
if err != nil {
return domain.Webhook{}, err
}
if name != nil {
wh.Name = *name
}
if url != nil {
wh.URL = *url
}
if events != nil {
wh.Events = *events
}
if enabled != nil {
wh.Enabled = *enabled
}
evts, _ := json.Marshal(wh.Events)
en := 0
if wh.Enabled {
en = 1
}
_, err = r.db.ExecContext(ctx,
`UPDATE webhooks SET name=?, url=?, events=?, enabled=? WHERE id=?`,
wh.Name, wh.URL, string(evts), en, id)
if err != nil {
return domain.Webhook{}, err
}
return wh, nil
}