mirror of
https://github.com/harness/drone.git
synced 2025-05-21 19:39:59 +08:00
add space descendants data layer fn (#2511)
* add space descendants data layer fn
This commit is contained in:
parent
7e3253d366
commit
d089d04025
@ -241,7 +241,7 @@ func (s *Service) ListPullReqLabels(
|
|||||||
pullreqID int64,
|
pullreqID int64,
|
||||||
filter *types.AssignableLabelFilter,
|
filter *types.AssignableLabelFilter,
|
||||||
) (*types.ScopesLabels, int64, error) {
|
) (*types.ScopesLabels, int64, error) {
|
||||||
spaces, err := s.spaceStore.GetHierarchy(ctx, spaceID)
|
spaces, err := s.spaceStore.GetAncestors(ctx, spaceID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, fmt.Errorf("failed to get space hierarchy: %w", err)
|
return nil, 0, fmt.Errorf("failed to get space hierarchy: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -169,10 +169,14 @@ type (
|
|||||||
// GetAncestorIDs returns a list of all space IDs along the recursive path to the root space.
|
// GetAncestorIDs returns a list of all space IDs along the recursive path to the root space.
|
||||||
GetAncestorIDs(ctx context.Context, spaceID int64) ([]int64, error)
|
GetAncestorIDs(ctx context.Context, spaceID int64) ([]int64, error)
|
||||||
|
|
||||||
GetHierarchy(
|
// GetAncestors returns a list of all spaces along the recursive path to the root space.
|
||||||
ctx context.Context,
|
GetAncestors(ctx context.Context, spaceID int64) ([]*types.Space, error)
|
||||||
spaceID int64,
|
|
||||||
) ([]*types.Space, error)
|
// GetAncestorsData returns a list of space parent data for spaces that are ancestors of the space.
|
||||||
|
GetAncestorsData(ctx context.Context, spaceID int64) ([]types.SpaceParentData, error)
|
||||||
|
|
||||||
|
// GetDescendantsData returns a list of space parent data for spaces that are descendants of the space.
|
||||||
|
GetDescendantsData(ctx context.Context, spaceID int64) ([]types.SpaceParentData, error)
|
||||||
|
|
||||||
// Create creates a new space
|
// Create creates a new space
|
||||||
Create(ctx context.Context, space *types.Space) error
|
Create(ctx context.Context, space *types.Space) error
|
||||||
|
@ -433,45 +433,7 @@ func (s *PullReqStore) Count(ctx context.Context, opts *types.PullReqFilter) (in
|
|||||||
}
|
}
|
||||||
stmt = stmt.From("pullreqs")
|
stmt = stmt.From("pullreqs")
|
||||||
|
|
||||||
if len(opts.States) == 1 {
|
s.applyFilter(&stmt, opts)
|
||||||
stmt = stmt.Where("pullreq_state = ?", opts.States[0])
|
|
||||||
} else if len(opts.States) > 1 {
|
|
||||||
stmt = stmt.Where(squirrel.Eq{"pullreq_state": opts.States})
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.SourceRepoID != 0 {
|
|
||||||
stmt = stmt.Where("pullreq_source_repo_id = ?", opts.SourceRepoID)
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.SourceBranch != "" {
|
|
||||||
stmt = stmt.Where("pullreq_source_branch = ?", opts.SourceBranch)
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.TargetRepoID != 0 {
|
|
||||||
stmt = stmt.Where("pullreq_target_repo_id = ?", opts.TargetRepoID)
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.TargetBranch != "" {
|
|
||||||
stmt = stmt.Where("pullreq_target_branch = ?", opts.TargetBranch)
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.Query != "" {
|
|
||||||
stmt = stmt.Where("LOWER(pullreq_title) LIKE ?", fmt.Sprintf("%%%s%%", strings.ToLower(opts.Query)))
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(opts.CreatedBy) > 0 {
|
|
||||||
stmt = stmt.Where(squirrel.Eq{"pullreq_created_by": opts.CreatedBy})
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.CreatedLt > 0 {
|
|
||||||
stmt = stmt.Where("pullreq_created < ?", opts.CreatedLt)
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.CreatedGt > 0 {
|
|
||||||
stmt = stmt.Where("pullreq_created > ?", opts.CreatedGt)
|
|
||||||
}
|
|
||||||
|
|
||||||
setLabelKeyQuery(&stmt, opts)
|
|
||||||
|
|
||||||
sql, args, err := stmt.ToSql()
|
sql, args, err := stmt.ToSql()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -500,45 +462,7 @@ func (s *PullReqStore) List(ctx context.Context, opts *types.PullReqFilter) ([]*
|
|||||||
}
|
}
|
||||||
stmt = stmt.From("pullreqs")
|
stmt = stmt.From("pullreqs")
|
||||||
|
|
||||||
if len(opts.States) == 1 {
|
s.applyFilter(&stmt, opts)
|
||||||
stmt = stmt.Where("pullreq_state = ?", opts.States[0])
|
|
||||||
} else if len(opts.States) > 1 {
|
|
||||||
stmt = stmt.Where(squirrel.Eq{"pullreq_state": opts.States})
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.SourceRepoID != 0 {
|
|
||||||
stmt = stmt.Where("pullreq_source_repo_id = ?", opts.SourceRepoID)
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.SourceBranch != "" {
|
|
||||||
stmt = stmt.Where("pullreq_source_branch = ?", opts.SourceBranch)
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.TargetRepoID != 0 {
|
|
||||||
stmt = stmt.Where("pullreq_target_repo_id = ?", opts.TargetRepoID)
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.TargetBranch != "" {
|
|
||||||
stmt = stmt.Where("pullreq_target_branch = ?", opts.TargetBranch)
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.Query != "" {
|
|
||||||
stmt = stmt.Where("LOWER(pullreq_title) LIKE ?", fmt.Sprintf("%%%s%%", strings.ToLower(opts.Query)))
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(opts.CreatedBy) > 0 {
|
|
||||||
stmt = stmt.Where(squirrel.Eq{"pullreq_created_by": opts.CreatedBy})
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.CreatedLt > 0 {
|
|
||||||
stmt = stmt.Where("pullreq_created < ?", opts.CreatedLt)
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.CreatedGt > 0 {
|
|
||||||
stmt = stmt.Where("pullreq_created > ?", opts.CreatedGt)
|
|
||||||
}
|
|
||||||
|
|
||||||
setLabelKeyQuery(&stmt, opts)
|
|
||||||
|
|
||||||
stmt = stmt.Limit(database.Limit(opts.Size))
|
stmt = stmt.Limit(database.Limit(opts.Size))
|
||||||
stmt = stmt.Offset(database.Offset(opts.Page, opts.Size))
|
stmt = stmt.Offset(database.Offset(opts.Page, opts.Size))
|
||||||
@ -570,7 +494,47 @@ func (s *PullReqStore) List(ctx context.Context, opts *types.PullReqFilter) ([]*
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setLabelKeyQuery(stmt *squirrel.SelectBuilder, opts *types.PullReqFilter) {
|
func (*PullReqStore) applyFilter(stmt *squirrel.SelectBuilder, opts *types.PullReqFilter) {
|
||||||
|
if len(opts.States) == 1 {
|
||||||
|
*stmt = stmt.Where("pullreq_state = ?", opts.States[0])
|
||||||
|
} else if len(opts.States) > 1 {
|
||||||
|
*stmt = stmt.Where(squirrel.Eq{"pullreq_state": opts.States})
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.SourceRepoID != 0 {
|
||||||
|
*stmt = stmt.Where("pullreq_source_repo_id = ?", opts.SourceRepoID)
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.SourceBranch != "" {
|
||||||
|
*stmt = stmt.Where("pullreq_source_branch = ?", opts.SourceBranch)
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.TargetRepoID != 0 {
|
||||||
|
*stmt = stmt.Where("pullreq_target_repo_id = ?", opts.TargetRepoID)
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.TargetBranch != "" {
|
||||||
|
*stmt = stmt.Where("pullreq_target_branch = ?", opts.TargetBranch)
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.Query != "" {
|
||||||
|
*stmt = stmt.Where("LOWER(pullreq_title) LIKE ?", fmt.Sprintf("%%%s%%", strings.ToLower(opts.Query)))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(opts.CreatedBy) > 0 {
|
||||||
|
*stmt = stmt.Where(squirrel.Eq{"pullreq_created_by": opts.CreatedBy})
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.CreatedLt > 0 {
|
||||||
|
*stmt = stmt.Where("pullreq_created < ?", opts.CreatedLt)
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.CreatedGt > 0 {
|
||||||
|
*stmt = stmt.Where("pullreq_created > ?", opts.CreatedGt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// labels
|
||||||
|
|
||||||
if len(opts.LabelID) == 0 && len(opts.ValueID) == 0 {
|
if len(opts.LabelID) == 0 && len(opts.ValueID) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -562,19 +562,9 @@ func (s *RepoStore) countAll(
|
|||||||
parentID int64,
|
parentID int64,
|
||||||
filter *types.RepoFilter,
|
filter *types.RepoFilter,
|
||||||
) (int64, error) {
|
) (int64, error) {
|
||||||
query := `WITH RECURSIVE SpaceHierarchy AS (
|
query := spaceDescendantsQuery + `
|
||||||
SELECT space_id, space_parent_id
|
SELECT space_descendant_id
|
||||||
FROM spaces
|
FROM space_descendants`
|
||||||
WHERE space_id = $1
|
|
||||||
|
|
||||||
UNION
|
|
||||||
|
|
||||||
SELECT s.space_id, s.space_parent_id
|
|
||||||
FROM spaces s
|
|
||||||
JOIN SpaceHierarchy h ON s.space_parent_id = h.space_id
|
|
||||||
)
|
|
||||||
SELECT space_id
|
|
||||||
FROM SpaceHierarchy h1;`
|
|
||||||
|
|
||||||
db := dbtx.GetAccessor(ctx, s.db)
|
db := dbtx.GetAccessor(ctx, s.db)
|
||||||
|
|
||||||
@ -649,24 +639,14 @@ func (s *RepoStore) listAll(
|
|||||||
parentID int64,
|
parentID int64,
|
||||||
filter *types.RepoFilter,
|
filter *types.RepoFilter,
|
||||||
) ([]*types.Repository, error) {
|
) ([]*types.Repository, error) {
|
||||||
where := `WITH RECURSIVE SpaceHierarchy AS (
|
query := spaceDescendantsQuery + `
|
||||||
SELECT space_id, space_parent_id
|
SELECT space_descendant_id
|
||||||
FROM spaces
|
FROM space_descendants`
|
||||||
WHERE space_id = $1
|
|
||||||
|
|
||||||
UNION
|
|
||||||
|
|
||||||
SELECT s.space_id, s.space_parent_id
|
|
||||||
FROM spaces s
|
|
||||||
JOIN SpaceHierarchy h ON s.space_parent_id = h.space_id
|
|
||||||
)
|
|
||||||
SELECT space_id
|
|
||||||
FROM SpaceHierarchy h1;`
|
|
||||||
|
|
||||||
db := dbtx.GetAccessor(ctx, s.db)
|
db := dbtx.GetAccessor(ctx, s.db)
|
||||||
|
|
||||||
var spaceIDs []int64
|
var spaceIDs []int64
|
||||||
if err := db.SelectContext(ctx, &spaceIDs, where, parentID); err != nil {
|
if err := db.SelectContext(ctx, &spaceIDs, query, parentID); err != nil {
|
||||||
return nil, database.ProcessSQLErrorf(ctx, err, "failed to retrieve spaces")
|
return nil, database.ProcessSQLErrorf(ctx, err, "failed to retrieve spaces")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,26 +192,40 @@ func (s *SpaceStore) findByPathAndDeletedAt(
|
|||||||
return s.find(ctx, spaceID, &deletedAt)
|
return s.find(ctx, spaceID, &deletedAt)
|
||||||
}
|
}
|
||||||
|
|
||||||
const spaceRecursiveQuery = `
|
const spaceAncestorsQuery = `
|
||||||
WITH RECURSIVE SpaceHierarchy(space_hierarchy_id, space_hierarchy_parent_id) AS (
|
WITH RECURSIVE space_ancestors(space_ancestor_id, space_ancestor_uid, space_ancestor_parent_id) AS (
|
||||||
SELECT space_id, space_parent_id
|
SELECT space_id, space_uid, space_parent_id
|
||||||
FROM spaces
|
FROM spaces
|
||||||
WHERE space_id = $1
|
WHERE space_id = $1
|
||||||
|
|
||||||
UNION
|
UNION
|
||||||
|
|
||||||
SELECT s.space_id, s.space_parent_id
|
SELECT space_id, space_uid, space_parent_id
|
||||||
FROM spaces s
|
FROM spaces
|
||||||
JOIN SpaceHierarchy h ON s.space_id = h.space_hierarchy_parent_id
|
JOIN space_ancestors ON space_id = space_ancestor_parent_id
|
||||||
|
)
|
||||||
|
`
|
||||||
|
|
||||||
|
const spaceDescendantsQuery = `
|
||||||
|
WITH RECURSIVE space_descendants(space_descendant_id, space_descendant_uid, space_descendant_parent_id) AS (
|
||||||
|
SELECT space_id, space_uid, space_parent_id
|
||||||
|
FROM spaces
|
||||||
|
WHERE space_id = $1
|
||||||
|
|
||||||
|
UNION
|
||||||
|
|
||||||
|
SELECT space_id, space_uid, space_parent_id
|
||||||
|
FROM spaces
|
||||||
|
JOIN space_descendants ON space_descendant_id = space_parent_id
|
||||||
)
|
)
|
||||||
`
|
`
|
||||||
|
|
||||||
// GetRootSpace returns a space where space_parent_id is NULL.
|
// GetRootSpace returns a space where space_parent_id is NULL.
|
||||||
func (s *SpaceStore) GetRootSpace(ctx context.Context, spaceID int64) (*types.Space, error) {
|
func (s *SpaceStore) GetRootSpace(ctx context.Context, spaceID int64) (*types.Space, error) {
|
||||||
query := spaceRecursiveQuery + `
|
query := spaceAncestorsQuery + `
|
||||||
SELECT space_hierarchy_id
|
SELECT space_ancestor_id
|
||||||
FROM SpaceHierarchy
|
FROM space_ancestors
|
||||||
WHERE space_hierarchy_parent_id IS NULL;`
|
WHERE space_ancestor_parent_id IS NULL`
|
||||||
|
|
||||||
db := dbtx.GetAccessor(ctx, s.db)
|
db := dbtx.GetAccessor(ctx, s.db)
|
||||||
|
|
||||||
@ -225,37 +239,93 @@ func (s *SpaceStore) GetRootSpace(ctx context.Context, spaceID int64) (*types.Sp
|
|||||||
|
|
||||||
// GetAncestorIDs returns a list of all space IDs along the recursive path to the root space.
|
// GetAncestorIDs returns a list of all space IDs along the recursive path to the root space.
|
||||||
func (s *SpaceStore) GetAncestorIDs(ctx context.Context, spaceID int64) ([]int64, error) {
|
func (s *SpaceStore) GetAncestorIDs(ctx context.Context, spaceID int64) ([]int64, error) {
|
||||||
query := spaceRecursiveQuery + `
|
query := spaceAncestorsQuery + `
|
||||||
SELECT space_hierarchy_id FROM SpaceHierarchy`
|
SELECT space_ancestor_id FROM space_ancestors`
|
||||||
|
|
||||||
db := dbtx.GetAccessor(ctx, s.db)
|
db := dbtx.GetAccessor(ctx, s.db)
|
||||||
|
|
||||||
var spaceIDs []int64
|
var spaceIDs []int64
|
||||||
if err := db.SelectContext(ctx, &spaceIDs, query, spaceID); err != nil {
|
if err := db.SelectContext(ctx, &spaceIDs, query, spaceID); err != nil {
|
||||||
return nil, database.ProcessSQLErrorf(ctx, err, "failed to get space hierarchy")
|
return nil, database.ProcessSQLErrorf(ctx, err, "failed to get space ancestors IDs")
|
||||||
}
|
}
|
||||||
|
|
||||||
return spaceIDs, nil
|
return spaceIDs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SpaceStore) GetHierarchy(
|
func (s *SpaceStore) GetAncestors(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
spaceID int64,
|
spaceID int64,
|
||||||
) ([]*types.Space, error) {
|
) ([]*types.Space, error) {
|
||||||
query := spaceRecursiveQuery + `
|
query := spaceAncestorsQuery + `
|
||||||
SELECT ` + spaceColumns + `
|
SELECT ` + spaceColumns + `
|
||||||
FROM spaces INNER JOIN SpaceHierarchy ON space_id = space_hierarchy_id`
|
FROM spaces INNER JOIN space_ancestors ON space_id = space_ancestor_id`
|
||||||
|
|
||||||
db := dbtx.GetAccessor(ctx, s.db)
|
db := dbtx.GetAccessor(ctx, s.db)
|
||||||
|
|
||||||
var dst []*space
|
var dst []*space
|
||||||
if err := db.SelectContext(ctx, &dst, query, spaceID); err != nil {
|
if err := db.SelectContext(ctx, &dst, query, spaceID); err != nil {
|
||||||
return nil, database.ProcessSQLErrorf(ctx, err, "Failed executing custom list query")
|
return nil, database.ProcessSQLErrorf(ctx, err, "Failed executing get space ancestors query")
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.mapToSpaces(ctx, s.db, dst)
|
return s.mapToSpaces(ctx, s.db, dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAncestorsData returns a list of space parent data for spaces that are ancestors of the space.
|
||||||
|
func (s *SpaceStore) GetAncestorsData(ctx context.Context, spaceID int64) ([]types.SpaceParentData, error) {
|
||||||
|
query := spaceAncestorsQuery + `
|
||||||
|
SELECT space_ancestor_id, space_ancestor_uid, space_ancestor_parent_id FROM space_ancestors`
|
||||||
|
|
||||||
|
return s.readParentsData(ctx, query, spaceID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDescendantsData returns a list of space parent data for spaces that are descendants of the space.
|
||||||
|
func (s *SpaceStore) GetDescendantsData(ctx context.Context, spaceID int64) ([]types.SpaceParentData, error) {
|
||||||
|
query := spaceDescendantsQuery + `
|
||||||
|
SELECT space_descendant_id, space_descendant_uid, space_descendant_parent_id FROM space_descendants`
|
||||||
|
|
||||||
|
return s.readParentsData(ctx, query, spaceID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SpaceStore) readParentsData(
|
||||||
|
ctx context.Context,
|
||||||
|
query string,
|
||||||
|
spaceID int64,
|
||||||
|
) ([]types.SpaceParentData, error) {
|
||||||
|
db := dbtx.GetAccessor(ctx, s.db)
|
||||||
|
|
||||||
|
rows, err := db.QueryContext(ctx, query, spaceID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, database.ProcessSQLErrorf(ctx, err, "failed to run space parent data query")
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() { _ = rows.Close() }()
|
||||||
|
|
||||||
|
var result []types.SpaceParentData
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
var id int64
|
||||||
|
var uid string
|
||||||
|
var parent null.Int
|
||||||
|
|
||||||
|
err = rows.Scan(&id, &uid, &parent)
|
||||||
|
if err != nil {
|
||||||
|
return nil, database.ProcessSQLErrorf(ctx, err, "failed to scan space parent data")
|
||||||
|
}
|
||||||
|
|
||||||
|
result = append(result, types.SpaceParentData{
|
||||||
|
ID: id,
|
||||||
|
Identifier: uid,
|
||||||
|
ParentID: parent.Int64,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, database.ProcessSQLErrorf(ctx, err, "failed to read space parent data")
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Create a new space.
|
// Create a new space.
|
||||||
func (s *SpaceStore) Create(ctx context.Context, space *types.Space) error {
|
func (s *SpaceStore) Create(ctx context.Context, space *types.Space) error {
|
||||||
if space == nil {
|
if space == nil {
|
||||||
|
@ -100,6 +100,8 @@ type RepositoryGitInfo struct {
|
|||||||
GitUID string
|
GitUID string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rgi *RepositoryGitInfo) GetGitUID() string { return rgi.GitUID }
|
||||||
|
|
||||||
type RepositoryPullReqSummary struct {
|
type RepositoryPullReqSummary struct {
|
||||||
OpenCount int `json:"open_count"`
|
OpenCount int `json:"open_count"`
|
||||||
ClosedCount int `json:"closed_count"`
|
ClosedCount int `json:"closed_count"`
|
||||||
|
@ -43,6 +43,12 @@ type Space struct {
|
|||||||
Deleted *int64 `json:"deleted,omitempty"`
|
Deleted *int64 `json:"deleted,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SpaceParentData struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Identifier string `json:"identifier"`
|
||||||
|
ParentID int64 `json:"parent_id"`
|
||||||
|
}
|
||||||
|
|
||||||
// Stores spaces query parameters.
|
// Stores spaces query parameters.
|
||||||
type SpaceFilter struct {
|
type SpaceFilter struct {
|
||||||
Page int `json:"page"`
|
Page int `json:"page"`
|
||||||
|
Loading…
Reference in New Issue
Block a user