Populate Repository.Owner in list/get store queries

ListReposVisible, GetRepositoryByName, and GetRepositoryByID left
Repository.Owner as nil because they only selected repository columns.
LEFT JOIN users in all three and populate Owner, so the API (and the
web UI's repositories table) can show the owner's username.
This commit is contained in:
2026-06-28 18:42:31 -05:00
parent c5e64cf63f
commit bff58fd842
+50 -10
View File
@@ -24,11 +24,13 @@ func (s *Store) CreateRepository(ctx context.Context, name, ownerUserID string,
}
// ListReposVisible returns repositories visible to userID: owned, public, or
// where the user is a member.
// where the user is a member. Each repository's Owner is populated.
func (s *Store) ListReposVisible(ctx context.Context, userID string) ([]*models.Repository, error) {
rows, err := s.db.QueryContext(ctx, `
SELECT DISTINCT r.id, r.name, r.owner_user_id, r.visibility, r.description, r.created_at, r.updated_at
SELECT DISTINCT r.id, r.name, r.owner_user_id, r.visibility, r.description, r.created_at, r.updated_at,
u.id, u.username, u.is_admin, u.created_at, u.updated_at
FROM repositories r
LEFT JOIN users u ON u.id = r.owner_user_id
WHERE r.owner_user_id = ?
OR r.visibility = 'public'
OR EXISTS (SELECT 1 FROM repository_members m WHERE m.repository_id = r.id AND m.user_id = ?)
@@ -40,9 +42,25 @@ func (s *Store) ListReposVisible(ctx context.Context, userID string) ([]*models.
var out []*models.Repository
for rows.Next() {
r := &models.Repository{}
if err := rows.Scan(&r.ID, &r.Name, &r.OwnerUserID, &r.Visibility, &r.Description, &r.CreatedAt, &r.UpdatedAt); err != nil {
var (
ownerID sql.NullString
ownerUser sql.NullString
ownerAdmin sql.NullBool
ownerCreated sql.NullString
ownerUpdated sql.NullString
)
if err := rows.Scan(
&r.ID, &r.Name, &r.OwnerUserID, &r.Visibility, &r.Description, &r.CreatedAt, &r.UpdatedAt,
&ownerID, &ownerUser, &ownerAdmin, &ownerCreated, &ownerUpdated,
); err != nil {
return nil, err
}
if ownerID.Valid {
r.Owner = &models.User{
ID: ownerID.String, Username: ownerUser.String, IsAdmin: ownerAdmin.Bool,
CreatedAt: ownerCreated.String, UpdatedAt: ownerUpdated.String,
}
}
out = append(out, r)
}
return out, rows.Err()
@@ -79,31 +97,53 @@ func (s *Store) DeleteRepository(ctx context.Context, id string) error {
return nil
}
// GetRepositoryByName returns a repository by its unique name.
// GetRepositoryByName returns a repository by its unique name, with Owner populated.
func (s *Store) GetRepositoryByName(ctx context.Context, name string) (*models.Repository, error) {
row := s.db.QueryRowContext(ctx,
`SELECT id, name, owner_user_id, visibility, description, created_at, updated_at
FROM repositories WHERE name = ?`, name)
`SELECT r.id, r.name, r.owner_user_id, r.visibility, r.description, r.created_at, r.updated_at,
u.id, u.username, u.is_admin, u.created_at, u.updated_at
FROM repositories r
LEFT JOIN users u ON u.id = r.owner_user_id
WHERE r.name = ?`, name)
return scanRepo(row)
}
// GetRepositoryByID returns a repository by id.
// GetRepositoryByID returns a repository by id, with Owner populated.
func (s *Store) GetRepositoryByID(ctx context.Context, id string) (*models.Repository, error) {
row := s.db.QueryRowContext(ctx,
`SELECT id, name, owner_user_id, visibility, description, created_at, updated_at
FROM repositories WHERE id = ?`, id)
`SELECT r.id, r.name, r.owner_user_id, r.visibility, r.description, r.created_at, r.updated_at,
u.id, u.username, u.is_admin, u.created_at, u.updated_at
FROM repositories r
LEFT JOIN users u ON u.id = r.owner_user_id
WHERE r.id = ?`, id)
return scanRepo(row)
}
func scanRepo(row *sql.Row) (*models.Repository, error) {
r := &models.Repository{}
err := row.Scan(&r.ID, &r.Name, &r.OwnerUserID, &r.Visibility, &r.Description, &r.CreatedAt, &r.UpdatedAt)
var (
ownerID sql.NullString
ownerUser sql.NullString
ownerAdmin sql.NullBool
ownerCreated sql.NullString
ownerUpdated sql.NullString
)
err := row.Scan(
&r.ID, &r.Name, &r.OwnerUserID, &r.Visibility, &r.Description, &r.CreatedAt, &r.UpdatedAt,
&ownerID, &ownerUser, &ownerAdmin, &ownerCreated, &ownerUpdated,
)
if isErrNoRows(err) {
return nil, ErrNotFound
}
if err != nil {
return nil, err
}
if ownerID.Valid {
r.Owner = &models.User{
ID: ownerID.String, Username: ownerUser.String, IsAdmin: ownerAdmin.Bool,
CreatedAt: ownerCreated.String, UpdatedAt: ownerUpdated.String,
}
}
return r, nil
}