MCPcopy Create free account
hub / github.com/bytebase/bytebase / ListIssues

Method ListIssues

backend/store/issue.go:278–443  ·  view source on GitHub ↗

ListIssues returns the list of issues by find query.

(ctx context.Context, find *FindIssueMessage)

Source from the content-addressed store, hash-verified

276
277// ListIssues returns the list of issues by find query.
278func (s *Store) ListIssues(ctx context.Context, find *FindIssueMessage) ([]*IssueMessage, error) {
279 orderByClause := "ORDER BY issue.id DESC"
280 from := qb.Q().Space("issue")
281 where := qb.Q()
282
283 // `ProjectIDs` is required: empty slice intentionally returns zero
284 // rows, which `SearchIssues` relies on as its IAM-derived "this user
285 // has access to no projects" guard. Skipping the filter on empty
286 // would leak cross-project issues. Cross-project runner scans must
287 // pre-collect the project ID set (e.g. via `ListProjects`) and pass
288 // the explicit list here.
289 if len(find.ProjectIDs) == 1 {
290 where.And("issue.project = ?", find.ProjectIDs[0])
291 } else {
292 where.And("issue.project = ANY(?)", find.ProjectIDs)
293 }
294 if find.Workspace != "" {
295 from.Space("JOIN project ON issue.project = project.resource_id")
296 where.And("project.workspace = ?", find.Workspace)
297 }
298
299 if v := find.UID; v != nil {
300 where.And("issue.id = ?", *v)
301 }
302 if v := find.PlanUID; v != nil {
303 where.And("issue.plan_id = ?", *v)
304 }
305 if v := find.PlanUIDs; v != nil {
306 where.And("issue.plan_id = ANY(?)", *v)
307 }
308
309 if v := find.CreatorID; v != nil {
310 where.And("issue.creator = ?", *v)
311 }
312 if v := find.CreatedAtBefore; v != nil {
313 where.And("issue.created_at < ?", *v)
314 }
315 if v := find.CreatedAtAfter; v != nil {
316 where.And("issue.created_at > ?", *v)
317 }
318 if v := find.Types; v != nil {
319 typeStrings := make([]string, 0, len(*v))
320 for _, t := range *v {
321 typeStrings = append(typeStrings, t.String())
322 }
323 where.And("issue.type = ANY(?)", typeStrings)
324 }
325 if v := find.Query; v != nil && *v != "" {
326 searchCondition := qb.Q()
327 if tsQuery := getTSQuery(*v); tsQuery != "" {
328 from.Space("LEFT JOIN CAST(? AS tsquery) AS query ON TRUE", tsQuery)
329 searchCondition.Or("issue.ts_vector @@ query")
330 orderByClause = "ORDER BY ts_rank(issue.ts_vector, query) DESC, issue.id DESC"
331 }
332 searchCondition.Or("issue.name ILIKE ?", "%"+*v+"%")
333 where.And("(?)", searchCondition)
334 }
335 if len(find.StatusList) != 0 {

Callers 1

GetIssueMethod · 0.95

Calls 15

GetDBMethod · 0.95
QFunction · 0.92
getTSQueryFunction · 0.85
SpaceMethod · 0.80
AndMethod · 0.80
OrMethod · 0.80
JoinMethod · 0.80
LenMethod · 0.80
ToSQLMethod · 0.80
QueryContextMethod · 0.80
ScanMethod · 0.80
ErrorfMethod · 0.80

Tested by

no test coverage detected