Files
devstar/services/devstar_devcontainer/UserDevcontainerService.go
戴明辰 4b6f1b9cb5 !6 k8s Agent for DevStar DevContainer
* DELETE /api/devcontainer?repoId=${repoId} 删除 DevContainer
* refactor
* GET /api/devcontainer?repoId=${repoId}&wait=true 阻塞式等待打开就绪的 DevContainer
* POST /api/devcontainer 创建 DevContainer
* refactored the code
* Updated context usage with cancel function
* 预留接口,适配单机版 DevStar DevContainer
* bugFix: context canceled while deleting k8s CRD DevcontainerApp
* 用户界面删除 k8s CRD DevContainer
* 用户界面创建 DevContainer 并更新 NodePort
* 完成用户界面创建 DevContainer
* transplant test code into DevStar Studio
* refactored API router to /routers/api
* 更改 DevContainer Doc
* 更改 DevContainer namespace
* 特殊仓库重定向
* [Doc] 更新 Kubernetes 部署 DevStar Studio 文档说明,特别是 namespace 管理
* [Doc] 更新 CI脚本说明
* Revert "optimized CI workflow"
* optimized CI workflow
* fix typo
* [feature test]: 测试 Pod 内使用 Kubernetes Operator 功能
* [Optimization] error msg for archived repo
* [Optimization]: display detailed err msg on creating devContainer for …
2024-09-30 06:48:01 +00:00

146 lines
6.2 KiB
Go

package devstar_devcontainer
import (
"code.gitea.io/gitea/models/db"
devstar_devcontainer_models "code.gitea.io/gitea/models/devstar_devcontainer"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/routers/api/devcontainer/vo"
"context"
"fmt"
"xorm.io/builder"
)
// GetUserDevcontainersList 根据 userId 查询名下 devContainer 列表
func GetUserDevcontainersList(ctx context.Context, opts *vo.SearchUserDevcontainerListItemVoOptions) (vo.ListUserDevcontainersVO, error) {
// 0. 构造异常返回时的空数据
var resultDevContainerListVO = vo.ListUserDevcontainersVO{
Page: 0,
PageSize: setting.UI.Admin.DevContainersPagingNum,
PageTotalNum: 0,
ItemTotalNum: 0,
DevContainers: []vo.RepoDevContainerVO{},
}
// 1. 查询参数预处理
if opts == nil || opts.Actor == nil {
return resultDevContainerListVO, devstar_devcontainer_models.ErrFailedToOperateDevstarDevcontainerDB{
Action: "construct query condition for devContainer user list",
Message: "invalid search condition",
}
}
resultDevContainerListVO.UserID = opts.Actor.ID
resultDevContainerListVO.Username = opts.Actor.Name
if len(opts.OrderBy) == 0 {
opts.OrderBy = "devcontainer_id DESC"
}
opts.PaginationOptions.ListAll = false // 强制使用分页查询,禁止一次性列举所有 devContainers
if opts.PaginationOptions.Page <= 0 { // 未指定页码/无效页码:查询第 1 页
opts.PaginationOptions.Page = 1
}
if opts.PaginationOptions.PageSize <= 0 || opts.PaginationOptions.PageSize > setting.UI.Admin.DevContainersPagingNum {
opts.PaginationOptions.PageSize = setting.UI.Admin.DevContainersPagingNum // /无效页面大小/超过每页最大限制:自动调整到系统最大开发容器页面大小
}
resultDevContainerListVO.Page = opts.PaginationOptions.Page
resultDevContainerListVO.PageSize = opts.PaginationOptions.PageSize
// 2. SQL 条件构建
sqlCondition := builder.NewCond()
sqlCondition = sqlCondition.And(builder.Eq{"user_id": opts.Actor.ID})
// 3. 开启数据库事务,进行分页查询,同时封装 VO
errDbTransaction := db.WithTx(ctx, func(ctx context.Context) error {
var err error
// 2.1 查询符合条件的记录总数
/*
SELECT COUNT(*)
FROM devstar_devcontainer
WHERE user_id = #{opts.Actor.ID}
*/
resultDevContainerListVO.ItemTotalNum, err = db.GetEngine(ctx).
Table("devstar_devcontainer").
Where(sqlCondition).
Count()
if err != nil {
return devstar_devcontainer_models.ErrFailedToOperateDevstarDevcontainerDB{
Action: "count devContainer item numbers",
Message: err.Error(),
}
}
if resultDevContainerListVO.ItemTotalNum == 0 {
return nil // 无符合记录,返回 nil 提交/结束 事务
}
// 2.2 计算分页参数
totalRecords := resultDevContainerListVO.ItemTotalNum
pageSize := int64(resultDevContainerListVO.PageSize)
resultDevContainerListVO.PageTotalNum = int(totalRecords / pageSize)
if totalRecords%pageSize > 0 {
resultDevContainerListVO.PageTotalNum += 1
}
// 2.3 数据库带条件分页查询
resultDevContainerListVO.DevContainers = make([]vo.RepoDevContainerVO, 0, opts.PaginationOptions.PageSize)
/*
SELECT
devstar_devcontainer.id AS devcontainer_id,
devstar_devcontainer.name AS devcontainer_name,
devstar_devcontainer.devcontainer_host AS devcontainer_host,
devstar_devcontainer.devcontainer_username AS devcontainer_username,
devstar_devcontainer.devcontainer_password AS devcontainer_password,
devstar_devcontainer.devcontainer_work_dir AS devcontainer_work_dir,
devstar_devcontainer.repo_id AS repo_id,
repository.name AS repo_name,
repository.owner_name AS repo_owner_name,
repository.description AS repo_description,
CONCAT('/', repository.owner_name, '/', repository.name) AS repo_link
FROM devstar_devcontainer
INNER JOIN repository ON devstar_devcontainer.repo_id = repository.id
WHERE devstar_devcontainer.user_id = #{opts.Actor.ID}
ORDER BY #{opts.OrderBy.String()}
LIMIT #{opts.PaginationOptions.PageSize}
OFFSET ( (#{opts.PaginationOptions.Page} - 1) * #{opts.PaginationOptions.PageSize});
*/
sess := db.GetEngine(ctx).
Table("devstar_devcontainer").
Select(""+
"devstar_devcontainer.id AS devcontainer_id,"+
"devstar_devcontainer.name AS devcontainer_name,"+
"devstar_devcontainer.devcontainer_host AS devcontainer_host,"+
"devstar_devcontainer.devcontainer_username AS devcontainer_username,"+
"devstar_devcontainer.devcontainer_password AS devcontainer_password,"+
"devstar_devcontainer.devcontainer_work_dir AS devcontainer_work_dir,"+
"devstar_devcontainer.repo_id AS repo_id,"+
"repository.name AS repo_name,"+
"repository.owner_name AS repo_owner_name,"+
"repository.description AS repo_description,"+
"CONCAT('/', repository.owner_name, '/', repository.name) AS repo_link").
Join("INNER", "repository", "devstar_devcontainer.repo_id = repository.id").
Where(sqlCondition).
OrderBy(opts.OrderBy.String())
err = db.SetSessionPagination(sess, &opts.PaginationOptions).
Find(&resultDevContainerListVO.DevContainers)
if err != nil {
// 查询出错,返回错误信息,结束事务
return devstar_devcontainer_models.ErrFailedToOperateDevstarDevcontainerDB{
Action: fmt.Sprintf("list devContainer for user '%v' at page %v", opts.Actor.Name, opts.PaginationOptions.Page),
Message: err.Error(),
}
}
// 2.4 查询完成,返回 nil 自动提交事务
return nil
})
if errDbTransaction != nil {
return resultDevContainerListVO,
devstar_devcontainer_models.ErrFailedToOperateDevstarDevcontainerDB{
Action: "query user DevContainer List",
Message: errDbTransaction.Error(),
}
}
return resultDevContainerListVO, nil
}