* fix `nil` parsed of `postCreateCommand` * parse undefined fields to `nil` ptr * Added JSON Unmarshaler with default values * Refactored DevContainer Model Errors * Added `DevContainerJSON` to unmarshal devcontainer.json
144 lines
6.1 KiB
Go
144 lines
6.1 KiB
Go
package devstar_devcontainer
|
|
|
|
import (
|
|
"code.gitea.io/gitea/models/db"
|
|
devstar_devcontainer_models "code.gitea.io/gitea/models/devstar_devcontainer/errors"
|
|
"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_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_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
|
|
}
|