package repo import ( "errors" "time" "voltaserve/errorpkg" "voltaserve/helper" "voltaserve/infra" "voltaserve/model" "gorm.io/gorm" ) type WorkspaceInsertOptions struct { ID string Name string StorageCapacity int64 Image *string OrganizationID string RootID string Bucket string } type WorkspaceRepo interface { Insert(opts WorkspaceInsertOptions) (model.Workspace, error) Find(id string) (model.Workspace, error) UpdateName(id string, name string) (model.Workspace, error) UpdateStorageCapacity(id string, storageCapacity int64) (model.Workspace, error) UpdateRootID(id string, rootNodeID string) error Delete(id string) error GetIDs() ([]string, error) GetIDsByOrganization(orgID string) ([]string, error) GrantUserPermission(id string, userID string, permission string) error } func NewWorkspaceRepo() WorkspaceRepo { return newWorkspaceRepo() } func NewWorkspace() model.Workspace { return &workspaceEntity{} } type workspaceEntity struct { ID string `json:"id," gorm:"column:id;size:36"` Name string `json:"name" gorm:"column:name;size:255"` StorageCapacity int64 `json:"storageCapacity" gorm:"column:storage_capacity"` RootID string `json:"rootId" gorm:"column:root_id;size:36"` OrganizationID string `json:"organizationId" gorm:"column:organization_id;size:36"` UserPermissions []*userPermissionValue `json:"userPermissions" gorm:"-"` GroupPermissions []*groupPermissionValue `json:"groupPermissions" gorm:"-"` Bucket string `json:"bucket" gorm:"column:bucket;size:255"` CreateTime string `json:"createTime" gorm:"column:create_time"` UpdateTime *string `json:"updateTime,omitempty" gorm:"column:update_time"` } func (*workspaceEntity) TableName() string { return "workspace" } func (w *workspaceEntity) BeforeCreate(*gorm.DB) (err error) { w.CreateTime = time.Now().UTC().Format(time.RFC3339) return nil } func (w *workspaceEntity) BeforeSave(*gorm.DB) (err error) { timeNow := time.Now().UTC().Format(time.RFC3339) w.UpdateTime = &timeNow return nil } func (w *workspaceEntity) GetID() string { return w.ID } func (w *workspaceEntity) GetName() string { return w.Name } func (w *workspaceEntity) GetStorageCapacity() int64 { return w.StorageCapacity } func (w *workspaceEntity) GetRootID() string { return w.RootID } func (w *workspaceEntity) GetOrganizationID() string { return w.OrganizationID } func (w *workspaceEntity) GetUserPermissions() []model.CoreUserPermission { var res []model.CoreUserPermission for _, p := range w.UserPermissions { res = append(res, p) } return res } func (w *workspaceEntity) GetGroupPermissions() []model.CoreGroupPermission { var res []model.CoreGroupPermission for _, p := range w.GroupPermissions { res = append(res, p) } return res } func (w *workspaceEntity) GetBucket() string { return w.Bucket } func (w *workspaceEntity) GetCreateTime() string { return w.CreateTime } func (w *workspaceEntity) GetUpdateTime() *string { return w.UpdateTime } func (w *workspaceEntity) SetName(name string) { w.Name = name } func (w *workspaceEntity) SetUpdateTime(updateTime *string) { w.UpdateTime = updateTime } type workspaceRepo struct { db *gorm.DB permissionRepo *permissionRepo } func newWorkspaceRepo() *workspaceRepo { return &workspaceRepo{ db: infra.GetDb(), permissionRepo: newPermissionRepo(), } } func (repo *workspaceRepo) Insert(opts WorkspaceInsertOptions) (model.Workspace, error) { var id string if len(opts.ID) > 0 { id = opts.ID } else { id = helper.NewID() } workspace := workspaceEntity{ ID: id, Name: opts.Name, StorageCapacity: opts.StorageCapacity, RootID: opts.RootID, OrganizationID: opts.OrganizationID, Bucket: opts.Bucket, } if db := repo.db.Save(&workspace); db.Error != nil { return nil, db.Error } res, err := repo.find(id) if err != nil { return nil, err } if err := repo.populateModelFields([]*workspaceEntity{res}); err != nil { return nil, err } return res, nil } func (repo *workspaceRepo) find(id string) (*workspaceEntity, error) { var res = workspaceEntity{} db := repo.db.Where("id = ?", id).First(&res) if db.Error != nil { if errors.Is(db.Error, gorm.ErrRecordNotFound) { return nil, errorpkg.NewWorkspaceNotFoundError(db.Error) } else { return nil, errorpkg.NewInternalServerError(db.Error) } } return &res, nil } func (repo *workspaceRepo) Find(id string) (model.Workspace, error) { workspace, err := repo.find(id) if err != nil { return nil, err } if err := repo.populateModelFields([]*workspaceEntity{workspace}); err != nil { return nil, err } return workspace, err } func (repo *workspaceRepo) UpdateName(id string, name string) (model.Workspace, error) { workspace, err := repo.find(id) if err != nil { return &workspaceEntity{}, err } workspace.Name = name if db := repo.db.Save(&workspace); db.Error != nil { return nil, db.Error } res, err := repo.Find(id) if err != nil { return nil, err } return res, nil } func (repo *workspaceRepo) UpdateStorageCapacity(id string, storageCapacity int64) (model.Workspace, error) { workspace, err := repo.find(id) if err != nil { return &workspaceEntity{}, err } workspace.StorageCapacity = storageCapacity db := repo.db.Save(&workspace) if db.Error != nil { return nil, db.Error } res, err := repo.Find(id) if err != nil { return nil, err } return res, nil } func (repo *workspaceRepo) UpdateRootID(id string, rootNodeID string) error { db := repo.db.Exec("UPDATE workspace SET root_id = ? WHERE id = ?", rootNodeID, id) if db.Error != nil { return db.Error } return nil } func (repo *workspaceRepo) Delete(id string) error { db := repo.db.Exec("DELETE FROM workspace WHERE id = ?", id) if db.Error != nil { return db.Error } db = repo.db.Exec("DELETE FROM userpermission WHERE resource_id = ?", id) if db.Error != nil { return db.Error } db = repo.db.Exec("DELETE FROM grouppermission WHERE resource_id = ?", id) if db.Error != nil { return db.Error } return nil } func (repo *workspaceRepo) GetIDs() ([]string, error) { type IDResult struct { Result string } var ids []IDResult db := repo.db.Raw("SELECT id result FROM workspace ORDER BY create_time DESC").Scan(&ids) if db.Error != nil { return []string{}, db.Error } res := []string{} for _, id := range ids { res = append(res, id.Result) } return res, nil } func (repo *workspaceRepo) GetIDsByOrganization(orgID string) ([]string, error) { type IDResult struct { Result string } var ids []IDResult db := repo.db. Raw("SELECT id result FROM workspace WHERE organization_id = ? ORDER BY create_time DESC", orgID). Scan(&ids) if db.Error != nil { return nil, db.Error } res := []string{} for _, id := range ids { res = append(res, id.Result) } return res, nil } func (repo *workspaceRepo) GrantUserPermission(id string, userID string, permission string) error { db := repo.db.Exec( "INSERT INTO userpermission (id, user_id, resource_id, permission) VALUES (?, ?, ?, ?) ON CONFLICT (user_id, resource_id) DO UPDATE SET permission = ?", helper.NewID(), userID, id, permission, permission) if db.Error != nil { return db.Error } return nil } func (repo *workspaceRepo) populateModelFields(workspaces []*workspaceEntity) error { for _, w := range workspaces { w.UserPermissions = make([]*userPermissionValue, 0) userPermissions, err := repo.permissionRepo.GetUserPermissions(w.ID) if err != nil { return err } for _, p := range userPermissions { w.UserPermissions = append(w.UserPermissions, &userPermissionValue{ UserID: p.UserID, Value: p.Permission, }) } w.GroupPermissions = make([]*groupPermissionValue, 0) groupPermissions, err := repo.permissionRepo.GetGroupPermissions(w.ID) if err != nil { return err } for _, p := range groupPermissions { w.GroupPermissions = append(w.GroupPermissions, &groupPermissionValue{ GroupID: p.GroupID, Value: p.Permission, }) } } return nil }