package devstar_devcontainer import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/devstar_devcontainer" "code.gitea.io/gitea/modules/setting" DevcontainersVO "code.gitea.io/gitea/routers/web/devcontainer/vo" "context" "fmt" "xorm.io/builder" ) // GetUserDevcontainersList 根据 userId 查询名下 devContainer 列表 func GetUserDevcontainersList(ctx context.Context, opts *DevcontainersVO.SearchDevcontainerItemVoOptions) (DevcontainersVO.ListUserDevcontainersVO, error) { // 0. 构造异常返回时的空数据 var resultDevContainerListVO = DevcontainersVO.ListUserDevcontainersVO{ Page: 0, PageSize: setting.UI.Admin.DevContainersPagingNum, PageTotalNum: 0, ItemTotalNum: 0, DevContainers: []DevcontainersVO.DevContainerItemVO{}, } // 1. 查询参数预处理 if opts == nil || opts.Actor == nil { return resultDevContainerListVO, devstar_devcontainer.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 { sess := db.GetEngine(ctx) var err error // 2.1 查询符合条件的记录总数 /* SELECT COUNT(*) FROM devstar_devcontainer LEFT JOIN repository ON devstar_devcontainer.repo_id = repository.id WHERE devstar_devcontainer.user_id = #{opts.Actor.ID} */ resultDevContainerListVO.ItemTotalNum, err = sess. Table("devstar_devcontainer"). Join("LEFT", "repository", "devstar_devcontainer.repo_id = repository.id"). Where(sqlCondition). Count() if err != nil { return devstar_devcontainer.ErrFailedToOperateDevstarDevcontainerDB{ Action: "count devContainer item numbers", Message: err.Error(), } } if resultDevContainerListVO.ItemTotalNum == 0 { return nil // 无符合记录,返回 nil 提交/结束 事务 } // 2.3 计算分页参数 totalRecords := resultDevContainerListVO.ItemTotalNum pageSize := int64(resultDevContainerListVO.PageSize) resultDevContainerListVO.PageTotalNum += int(totalRecords/pageSize) + 1 // 2.3 数据库带条件分页查询 resultDevContainerListVO.DevContainers = make([]DevcontainersVO.DevContainerItemVO, 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_port AS devcontainer_port, devstar_devcontainer.devcontainer_username AS devcontainer_username, devstar_devcontainer.devcontainer_password AS devcontainer_password, devstar_devcontainer.devcontainer_work_dir AS devcontainer_work_dir, repository.id AS repo_id, repository.name AS repo_name, repository.description AS repo_description FROM devstar_devcontainer LEFT 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 = sess. Table("devstar_devcontainer"). Select("devstar_devcontainer.repo_id AS repo_id, repository.name AS repo_name, repository.description AS repo_description, devstar_devcontainer.id AS devcontainer_id, devstar_devcontainer.name AS devcontainer_name, devstar_devcontainer.devcontainer_host AS devcontainer_host, devstar_devcontainer.devcontainer_port AS devcontainer_port, devstar_devcontainer.devcontainer_username AS devcontainer_username, devstar_devcontainer.devcontainer_password AS devcontainer_password, devstar_devcontainer.devcontainer_work_dir AS devcontainer_work_dir"). Join("LEFT", "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.ErrFailedToOperateDevstarDevcontainerDB{ Action: fmt.Sprintf("list devContainer for user '%v' at page %v", opts.Actor.Name, opts.PaginationOptions.Page), Message: err.Error(), } } // 2.x 查询完成,返回 nil 自动提交事务 return nil }) if errDbTransaction != nil { return resultDevContainerListVO, devstar_devcontainer.ErrFailedToOperateDevstarDevcontainerDB{ Action: "query user DevContainer List", Message: errDbTransaction.Error(), } } return resultDevContainerListVO, nil }