From f242cdbdd9eb0cad3d16f8e69858259cc7479d67 Mon Sep 17 00:00:00 2001 From: yokowu <18836617@qq.com> Date: Wed, 5 Aug 2026 14:03:57 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=99=9A=E6=8B=9F?= =?UTF-8?q?=E6=9C=BA=E5=9B=9E=E6=94=B6=E6=A0=A1=E9=AA=8C=E5=92=8C=E5=AE=A1?= =?UTF-8?q?=E8=AE=A1=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/biz/host/usecase/host.go | 50 +- backend/biz/task/usecase/task.go | 14 +- backend/biz/vmidle/usecase/policy_test.go | 162 ++- backend/biz/vmidle/usecase/vmidle.go | 176 +++- backend/consts/host.go | 12 + backend/db/client.go | 375 ++++--- backend/db/ent.go | 110 +- backend/db/hook/hook.go | 12 + backend/db/intercept/intercept.go | 30 + backend/db/migrate/schema.go | 35 + backend/db/mutation.go | 912 +++++++++++++++- backend/db/page.go | 14 + backend/db/predicate/predicate.go | 3 + backend/db/runtime/runtime.go | 11 + backend/db/tx.go | 3 + backend/db/virtualmachinerecyclerecord.go | 208 ++++ .../virtualmachinerecyclerecord.go | 115 +++ .../db/virtualmachinerecyclerecord/where.go | 532 ++++++++++ .../db/virtualmachinerecyclerecord_create.go | 971 ++++++++++++++++++ .../db/virtualmachinerecyclerecord_delete.go | 88 ++ .../db/virtualmachinerecyclerecord_query.go | 578 +++++++++++ .../db/virtualmachinerecyclerecord_update.go | 525 ++++++++++ backend/domain/host.go | 3 +- .../ent/schema/virtualmachinerecyclerecord.go | 46 + ...te_virtualmachine_recycle_records.down.sql | 1 + ...eate_virtualmachine_recycle_records.up.sql | 18 + backend/pkg/delayqueue/delayqueue.go | 6 + backend/pkg/delayqueue/delayqueue_test.go | 28 + backend/pkg/lifecycle/types.go | 11 +- backend/pkg/lifecycle/vmrecyclehook.go | 9 +- backend/pkg/lifecycle/vmrecyclehook_test.go | 9 +- backend/pkg/register.go | 1 + backend/pkg/vmrecycle/deadline_repair.go | 11 +- backend/pkg/vmrecycle/record.go | 57 + backend/pkg/vmrecycle/vmrecycle.go | 42 +- backend/pkg/vmrecycle/vmrecycle_test.go | 47 +- 36 files changed, 4906 insertions(+), 319 deletions(-) create mode 100644 backend/db/virtualmachinerecyclerecord.go create mode 100644 backend/db/virtualmachinerecyclerecord/virtualmachinerecyclerecord.go create mode 100644 backend/db/virtualmachinerecyclerecord/where.go create mode 100644 backend/db/virtualmachinerecyclerecord_create.go create mode 100644 backend/db/virtualmachinerecyclerecord_delete.go create mode 100644 backend/db/virtualmachinerecyclerecord_query.go create mode 100644 backend/db/virtualmachinerecyclerecord_update.go create mode 100644 backend/ent/schema/virtualmachinerecyclerecord.go create mode 100644 backend/migration/000025_create_virtualmachine_recycle_records.down.sql create mode 100644 backend/migration/000025_create_virtualmachine_recycle_records.up.sql create mode 100644 backend/pkg/vmrecycle/record.go diff --git a/backend/biz/host/usecase/host.go b/backend/biz/host/usecase/host.go index 867d16341..3ed49370d 100644 --- a/backend/biz/host/usecase/host.go +++ b/backend/biz/host/usecase/host.go @@ -27,9 +27,9 @@ import ( "github.com/chaitin/MonkeyCode/backend/errcode" "github.com/chaitin/MonkeyCode/backend/pkg/cvt" "github.com/chaitin/MonkeyCode/backend/pkg/delayqueue" - "github.com/chaitin/MonkeyCode/backend/pkg/entx" "github.com/chaitin/MonkeyCode/backend/pkg/random" "github.com/chaitin/MonkeyCode/backend/pkg/taskflow" + "github.com/chaitin/MonkeyCode/backend/pkg/vmrecycle" "github.com/chaitin/MonkeyCode/backend/pkg/vmstatus" "github.com/chaitin/MonkeyCode/backend/templates" ) @@ -44,6 +44,7 @@ type HostUsecase struct { userRepo domain.UserRepo girepo domain.GitIdentityRepo vmexpireQueue *delayqueue.VMExpireQueue + recycler vmrecycle.Recycler privilegeChecker domain.PrivilegeChecker // 可选,由内部项目通过 WithPrivilegeChecker 注入 tokenProvider *gituc.TokenProvider } @@ -59,6 +60,7 @@ func NewHostUsecase(i *do.Injector) (domain.HostUsecase, error) { userRepo: do.MustInvoke[domain.UserRepo](i), girepo: do.MustInvoke[domain.GitIdentityRepo](i), vmexpireQueue: do.MustInvoke[*delayqueue.VMExpireQueue](i), + recycler: do.MustInvoke[vmrecycle.Recycler](i), tokenProvider: do.MustInvoke[*gituc.TokenProvider](i), } @@ -109,36 +111,8 @@ func (h *HostUsecase) vmexpireConsumer() { err := h.vmexpireQueue.StartConsumer(context.Background(), VM_EXPIRE_QUEUE_KEY, func(ctx context.Context, job *delayqueue.Job[*domain.VmExpireInfo]) error { innerLogger := logger.With("job", job) innerLogger.InfoContext(ctx, "received expired virtualmachine") - - ctx = entx.SkipSoftDelete(ctx) - vm, err := h.repo.GetVirtualMachine(ctx, job.Payload.VmID) - if err != nil { - innerLogger.ErrorContext(ctx, "failed to get vm", "error", err) - return nil - } - - if err := h.taskflow.VirtualMachiner().Delete(ctx, &taskflow.DeleteVirtualMachineReq{ - UserID: vm.UserID.String(), - HostID: vm.HostID, - ID: vm.EnvironmentID, - }); err != nil { - innerLogger.ErrorContext(ctx, "failed to delete vm", "error", err) - } - - if err := h.repo.UpdateVirtualMachine(ctx, vm.ID, func(vmuo *db.VirtualMachineUpdateOne) error { - vmuo.SetIsRecycled(true) - return nil - }); err != nil { - innerLogger.ErrorContext(ctx, "failed to update vm", "error", err) - return err - } - - if err := h.markRecycledTasksFinished(ctx, vm); err != nil { - innerLogger.ErrorContext(ctx, "failed to finish recycled tasks", "error", err) - return err - } - - return nil + _, err := h.recycler.ForceRecycle(ctx, job.Payload.VmID, consts.VMRecycleMethodExpired) + return err }) h.logger.With("error", err, "index", index).WarnContext(context.Background(), "start consumer error retrying...") @@ -534,15 +508,13 @@ func (h *HostUsecase) CreateVM(ctx context.Context, user *domain.User, req *doma // DeleteVM 删除虚拟机 func (h *HostUsecase) DeleteVM(ctx context.Context, uid uuid.UUID, hostID, vmID string) error { h.logger.InfoContext(ctx, "delete vm", "vmID", vmID, "user_id", uid, "host_id", hostID) + if _, err := h.repo.GetVirtualMachineWithUser(ctx, uid, vmID); err != nil { + return err + } + if _, err := h.recycler.ForceRecycle(ctx, vmID, consts.VMRecycleMethodManualDelete); err != nil { + return err + } return h.repo.DeleteVirtualMachine(ctx, uid, hostID, vmID, func(vm *db.VirtualMachine) error { - if err := h.taskflow.VirtualMachiner().Delete(ctx, &taskflow.DeleteVirtualMachineReq{ - UserID: uid.String(), - HostID: vm.HostID, - ID: vm.EnvironmentID, - }); err != nil { - h.logger.ErrorContext(ctx, "failed to delete vm", "error", err) - } - // 清理 expired_at 过期队列中的残留任务 _ = h.vmexpireQueue.Remove(ctx, VM_EXPIRE_QUEUE_KEY, vm.ID) diff --git a/backend/biz/task/usecase/task.go b/backend/biz/task/usecase/task.go index 9ebb67793..c37068a01 100644 --- a/backend/biz/task/usecase/task.go +++ b/backend/biz/task/usecase/task.go @@ -369,9 +369,10 @@ func (a *TaskUsecase) Stop(ctx context.Context, user *domain.User, id uuid.UUID) // 通过 lifecycle 回收 VM if vm := tk.VirtualMachine; vm != nil { if err := a.vmLifecycle.Transition(ctx, vm.ID, lifecycle.VMStateRecycled, lifecycle.VMMetadata{ - VMID: vm.ID, - TaskID: &id, - UserID: user.ID, + VMID: vm.ID, + TaskID: &id, + UserID: user.ID, + RecycleMethod: consts.VMRecycleMethodTaskStop, }); err != nil { a.logger.WarnContext(ctx, "vm recycle transition failed", "error", err, "vm_id", vm.ID) } @@ -1069,9 +1070,10 @@ func (a *TaskUsecase) Delete(ctx context.Context, user *domain.User, id uuid.UUI vm := vms[0] if !vm.IsRecycled { if err := a.vmLifecycle.Transition(ctx, vm.ID, lifecycle.VMStateRecycled, lifecycle.VMMetadata{ - VMID: vm.ID, - TaskID: &id, - UserID: user.ID, + VMID: vm.ID, + TaskID: &id, + UserID: user.ID, + RecycleMethod: consts.VMRecycleMethodTaskDelete, }); err != nil { a.logger.WarnContext(ctx, "vm recycle transition failed on delete", "error", err, "vm_id", vm.ID) } diff --git a/backend/biz/vmidle/usecase/policy_test.go b/backend/biz/vmidle/usecase/policy_test.go index 50964b793..7d52320fd 100644 --- a/backend/biz/vmidle/usecase/policy_test.go +++ b/backend/biz/vmidle/usecase/policy_test.go @@ -14,6 +14,7 @@ import ( "github.com/redis/go-redis/v9" "github.com/chaitin/MonkeyCode/backend/config" + "github.com/chaitin/MonkeyCode/backend/consts" "github.com/chaitin/MonkeyCode/backend/db" "github.com/chaitin/MonkeyCode/backend/db/enttest" "github.com/chaitin/MonkeyCode/backend/db/virtualmachine" @@ -333,6 +334,133 @@ func TestRecycleJobRetriesMarkWithoutDeletingRemotelyAgain(t *testing.T) { } } +func TestRecycleJobReschedulesForRecentPostgresActivity(t *testing.T) { + now := time.Now() + taskID := uuid.New() + vm := &db.VirtualMachine{ + ID: "vm-recent-pg", + Edges: db.VirtualMachineEdges{Tasks: []*db.Task{{ + ID: taskID, + }}}, + } + taskRepo := &recycleGuardTaskRepoStub{task: &db.Task{ID: taskID, LastActiveAt: now.Add(-time.Minute)}} + recycler := &idleRecyclerStub{} + r := newRecycleGuardRefresher(t, vm, taskRepo, &taskLogActivityStub{latest: now.Add(-2 * time.Hour)}, recycler) + if err := r.redis.Set(context.Background(), "vm:idle:debounce:"+vm.ID+":activity", "1", time.Minute).Err(); err != nil { + t.Fatal(err) + } + + err := r.handleRecycleJob(context.Background(), &delayqueue.Job[*domain.VmIdleInfo]{ + Payload: &domain.VmIdleInfo{VmID: vm.ID, RecycleMethod: consts.VMRecycleMethodIdle}, + }) + if !errors.Is(err, delayqueue.ErrJobRescheduled) { + t.Fatalf("error = %v, want rescheduled", err) + } + if recycler.calls != 0 || taskRepo.calls != 1 { + t.Fatalf("recycle calls = %d, task calls = %d", recycler.calls, taskRepo.calls) + } + if _, _, ok, err := r.recycleQueue.GetJobInfo(context.Background(), vmrecycle.RecycleQueueKey, vm.ID); err != nil || !ok { + t.Fatalf("rescheduled job ok = %v, err = %v", ok, err) + } +} + +func TestRecycleJobReschedulesForRecentClickHouseActivity(t *testing.T) { + now := time.Now() + taskID := uuid.New() + vm := &db.VirtualMachine{ + ID: "vm-recent-clickhouse", + Edges: db.VirtualMachineEdges{Tasks: []*db.Task{{ + ID: taskID, + }}}, + } + taskRepo := &recycleGuardTaskRepoStub{task: &db.Task{ID: taskID, LastActiveAt: now.Add(-2 * time.Hour)}} + recycler := &idleRecyclerStub{} + r := newRecycleGuardRefresher(t, vm, taskRepo, &taskLogActivityStub{latest: now.Add(-time.Minute)}, recycler) + + err := r.handleRecycleJob(context.Background(), &delayqueue.Job[*domain.VmIdleInfo]{ + Payload: &domain.VmIdleInfo{VmID: vm.ID, RecycleMethod: consts.VMRecycleMethodIdle}, + }) + if !errors.Is(err, delayqueue.ErrJobRescheduled) { + t.Fatalf("error = %v, want rescheduled", err) + } + if recycler.calls != 0 || taskRepo.calls != 0 { + t.Fatalf("recycle calls = %d, task calls = %d", recycler.calls, taskRepo.calls) + } +} + +func TestRecycleJobKeepsRetryingWhenActivityCheckFails(t *testing.T) { + taskID := uuid.New() + vm := &db.VirtualMachine{ + ID: "vm-activity-check-error", + Edges: db.VirtualMachineEdges{Tasks: []*db.Task{{ + ID: taskID, + }}}, + } + wantErr := errors.New("clickhouse unavailable") + recycler := &idleRecyclerStub{} + r := newRecycleGuardRefresher(t, vm, &recycleGuardTaskRepoStub{}, &taskLogActivityStub{err: wantErr}, recycler) + + err := r.handleRecycleJob(context.Background(), &delayqueue.Job[*domain.VmIdleInfo]{ + Payload: &domain.VmIdleInfo{VmID: vm.ID, RecycleMethod: consts.VMRecycleMethodIdle}, + }) + if !errors.Is(err, wantErr) || !errors.Is(err, delayqueue.ErrRetryAfterMaxAttempts) { + t.Fatalf("error = %v, want activity and persistent retry errors", err) + } + if recycler.calls != 0 { + t.Fatalf("recycle calls = %d, want 0", recycler.calls) + } +} + +func TestRecycleJobContinuesWhenBothActivityChecksAreStale(t *testing.T) { + now := time.Now() + taskID := uuid.New() + vm := &db.VirtualMachine{ + ID: "vm-stale-activity", + Edges: db.VirtualMachineEdges{Tasks: []*db.Task{{ + ID: taskID, + }}}, + } + recycler := &idleRecyclerStub{} + r := newRecycleGuardRefresher(t, vm, + &recycleGuardTaskRepoStub{task: &db.Task{ID: taskID, LastActiveAt: now.Add(-2 * time.Hour)}}, + &taskLogActivityStub{latest: now.Add(-2 * time.Hour)}, + recycler, + ) + + if err := r.handleRecycleJob(context.Background(), &delayqueue.Job[*domain.VmIdleInfo]{ + Payload: &domain.VmIdleInfo{VmID: vm.ID, RecycleMethod: consts.VMRecycleMethodIdle}, + }); err != nil { + t.Fatal(err) + } + if recycler.calls != 1 { + t.Fatalf("recycle calls = %d, want 1", recycler.calls) + } +} + +func TestRecycleJobRepairsAlreadyRecycledVM(t *testing.T) { + vm := &db.VirtualMachine{ID: "vm-already-recycled", IsRecycled: true} + recycler := &idleRecyclerStub{} + r := newRecycleGuardRefresher(t, vm, &recycleGuardTaskRepoStub{}, &taskLogActivityStub{}, recycler) + + if err := r.handleRecycleJob(context.Background(), &delayqueue.Job[*domain.VmIdleInfo]{ + Payload: &domain.VmIdleInfo{VmID: vm.ID, RecycleMethod: consts.VMRecycleMethodIdle}, + }); err != nil { + t.Fatal(err) + } + if recycler.calls != 1 { + t.Fatalf("recycle calls = %d, want repair call", recycler.calls) + } +} + +func newRecycleGuardRefresher(t *testing.T, vm *db.VirtualMachine, taskRepo domain.TaskRepo, activity taskLogActivityReader, recycler vmrecycle.Recycler) *vmIdleRefresher { + t.Helper() + r := newQueueTestVMIdleRefresher(newTestRedis(t), &refreshHostRepoStub{vm: vm}) + r.taskRepo = taskRepo + r.taskLogActivity = activity + r.recycler = recycler + return r +} + func newQueueTestVMIdleRefresher(redisClient *redis.Client, repo domain.HostRepo) *vmIdleRefresher { logger := slog.Default() return &vmIdleRefresher{ @@ -409,11 +537,43 @@ type idleRecyclerStub struct { calls int } -func (s *idleRecyclerStub) Recycle(_ context.Context, vmID string) (vmrecycle.Result, error) { +type recycleGuardTaskRepoStub struct { + domain.TaskRepo + task *db.Task + err error + calls int +} + +func (s *recycleGuardTaskRepoStub) GetByID(context.Context, uuid.UUID) (*db.Task, error) { + s.calls++ + return s.task, s.err +} + +type taskLogActivityStub struct { + latest time.Time + ok bool + err error +} + +func (s *taskLogActivityStub) LatestTaskLogTime(context.Context, uuid.UUID) (time.Time, bool, error) { + if s.err != nil { + return time.Time{}, false, s.err + } + if !s.ok && s.latest.IsZero() { + return time.Time{}, false, nil + } + return s.latest, true, nil +} + +func (s *idleRecyclerStub) Recycle(_ context.Context, vmID string, _ consts.VMRecycleMethod) (vmrecycle.Result, error) { s.calls++ return vmrecycle.Result{VMID: vmID}, s.err } +func (s *idleRecyclerStub) ForceRecycle(context.Context, string, consts.VMRecycleMethod) (vmrecycle.Result, error) { + return vmrecycle.Result{}, errors.New("not implemented") +} + type refreshTeamPolicyRepoStub struct { team *db.Team } diff --git a/backend/biz/vmidle/usecase/vmidle.go b/backend/biz/vmidle/usecase/vmidle.go index 9e5c2a84f..861b17d33 100644 --- a/backend/biz/vmidle/usecase/vmidle.go +++ b/backend/biz/vmidle/usecase/vmidle.go @@ -17,6 +17,7 @@ import ( "github.com/chaitin/MonkeyCode/backend/consts" "github.com/chaitin/MonkeyCode/backend/db" "github.com/chaitin/MonkeyCode/backend/domain" + "github.com/chaitin/MonkeyCode/backend/pkg/clickhouse" "github.com/chaitin/MonkeyCode/backend/pkg/delayqueue" "github.com/chaitin/MonkeyCode/backend/pkg/notify/dispatcher" "github.com/chaitin/MonkeyCode/backend/pkg/taskflow" @@ -106,9 +107,15 @@ type vmIdleRefresher struct { notifyQueue *delayqueue.VMNotifyQueue recycleQueue *delayqueue.VMRecycleQueue recycler vmrecycle.Recycler + recorder vmrecycle.Recorder + taskLogActivity taskLogActivityReader schedules []notifySchedule } +type taskLogActivityReader interface { + LatestTaskLogTime(ctx context.Context, taskID uuid.UUID) (time.Time, bool, error) +} + type vmIdleNotifyJob struct { MemberSuffix string RunAt time.Time @@ -130,6 +137,10 @@ const ( func NewVMIdleRefresher(i *do.Injector) (VMIdleRefresher, error) { cfg := do.MustInvoke[*config.Config](i) + taskLogActivity, err := do.Invoke[*clickhouse.Client](i) + if err != nil { + return nil, err + } r := &vmIdleRefresher{ cfg: cfg, redis: do.MustInvoke[*redis.Client](i), @@ -143,6 +154,8 @@ func NewVMIdleRefresher(i *do.Injector) (VMIdleRefresher, error) { notifyQueue: do.MustInvoke[*delayqueue.VMNotifyQueue](i), recycleQueue: do.MustInvoke[*delayqueue.VMRecycleQueue](i), recycler: do.MustInvoke[vmrecycle.Recycler](i), + recorder: do.MustInvoke[vmrecycle.Recorder](i), + taskLogActivity: taskLogActivity, schedules: buildNotifySchedules(cfg.VMIdle), } @@ -271,7 +284,10 @@ func (r *vmIdleRefresher) refresh(ctx context.Context, vmID string, mode vmIdleR r.logger.DebugContext(ctx, "skip idle timer for countdown VM", "vmID", vmID) return nil } + return r.applyRefresh(ctx, vm, mode) +} +func (r *vmIdleRefresher) applyRefresh(ctx context.Context, vm *db.VirtualMachine, mode vmIdleRefreshMode) error { policy, err := r.resolvePolicyForVM(ctx, vm) if err != nil { return err @@ -282,16 +298,17 @@ func (r *vmIdleRefresher) refresh(ctx context.Context, vmID string, mode vmIdleR recycleAt = *plan.RecycleAt } payload := &domain.VmIdleInfo{ - UID: vm.UserID, - VmID: vm.ID, - HostID: vm.HostID, - EnvID: vm.EnvironmentID, - RecycleAt: recycleAt, + UID: vm.UserID, + VmID: vm.ID, + HostID: vm.HostID, + EnvID: vm.EnvironmentID, + RecycleAt: recycleAt, + RecycleMethod: consts.VMRecycleMethodIdle, } if mode == vmIdleKeepAwakeMode { - return r.applySleepPlan(ctx, vmID, payload, plan) + return r.applySleepPlan(ctx, vm.ID, payload, plan) } - return r.applyActivityPlan(ctx, vmID, payload, policy, plan) + return r.applyActivityPlan(ctx, vm.ID, payload, policy, plan) } func (r *vmIdleRefresher) applySleepPlan(ctx context.Context, vmID string, payload *domain.VmIdleInfo, plan vmIdleSchedulePlan) error { @@ -470,8 +487,30 @@ func (r *vmIdleRefresher) handleRecycleJob(ctx context.Context, job *delayqueue. if job.Payload.RecycleDeleteExhausted { return r.markRecycledForReconnectCompensation(ctx, job, nil) } + method := job.Payload.RecycleMethod + if method == "" { + method = consts.VMRecycleMethodIdle + } + if method == consts.VMRecycleMethodIdle && r.cfg != nil { + vm, err := r.hostRepo.GetVirtualMachine(ctx, vmID) + if err != nil { + if db.IsNotFound(err) { + return nil + } + return errors.Join(delayqueue.ErrRetryAfterMaxAttempts, fmt.Errorf("get vm %s before recycle: %w", vmID, err)) + } + if !vm.IsRecycled { + skip, err := r.shouldSkipRecycleForRecentActivity(ctx, vm, time.Now()) + if err != nil { + return errors.Join(delayqueue.ErrRetryAfterMaxAttempts, err) + } + if skip { + return delayqueue.ErrJobRescheduled + } + } + } logger.InfoContext(ctx, "vm recycle triggered", "attempt", job.Attempts+1) - _, err := r.recycler.Recycle(ctx, vmID) + _, err := r.recycler.Recycle(ctx, vmID, method) if err == nil { return nil } @@ -484,6 +523,10 @@ func (r *vmIdleRefresher) handleRecycleJob(ctx context.Context, job *delayqueue. func (r *vmIdleRefresher) markRecycledForReconnectCompensation(ctx context.Context, job *delayqueue.Job[*domain.VmIdleInfo], remoteErr error) error { vmID := job.Payload.VmID + vm, getErr := r.hostRepo.GetVirtualMachine(ctx, vmID) + if getErr != nil && !db.IsNotFound(getErr) { + return errors.Join(delayqueue.ErrRetryAfterMaxAttempts, remoteErr, fmt.Errorf("get vm %s before recycle compensation: %w", vmID, getErr)) + } if err := r.hostRepo.UpdateVirtualMachine(ctx, vmID, func(up *db.VirtualMachineUpdateOne) error { up.SetIsRecycled(true) return nil @@ -494,6 +537,30 @@ func (r *vmIdleRefresher) markRecycledForReconnectCompensation(ctx context.Conte fmt.Errorf("mark vm %s recycled after remote delete retries exhausted: %w", vmID, err), ) } + method := job.Payload.RecycleMethod + if method == "" { + method = consts.VMRecycleMethodIdle + } + if r.recorder != nil { + record := vmrecycle.Record{ + VMID: vmID, + EnvironmentID: job.Payload.EnvID, + HostID: job.Payload.HostID, + UserID: job.Payload.UID, + Method: method, + RemoteDeleted: false, + RecycledAt: time.Now(), + } + if vm != nil { + record.EnvironmentID = vm.EnvironmentID + record.HostID = vm.HostID + record.UserID = vm.UserID + record.TaskIDs = vmTaskIDs(vm) + } + if err := r.recorder.Create(ctx, record); err != nil { + return errors.Join(delayqueue.ErrRetryAfterMaxAttempts, remoteErr, fmt.Errorf("record vm %s recycle compensation: %w", vmID, err)) + } + } r.logger.With("fn", "recycleConsumer", "vm_id", vmID).WarnContext(ctx, "vm remote delete retries exhausted, marked recycled for agent reconnect compensation", "attempts", job.Attempts+1, @@ -502,6 +569,99 @@ func (r *vmIdleRefresher) markRecycledForReconnectCompensation(ctx context.Conte return nil } +func (r *vmIdleRefresher) shouldSkipRecycleForRecentActivity(ctx context.Context, vm *db.VirtualMachine, now time.Time) (bool, error) { + policy, err := r.resolvePolicyForVM(ctx, vm) + if err != nil { + return false, err + } + if !policy.RecycleEnabled || policy.EffectiveRecycleSeconds <= 0 { + return false, nil + } + + taskIDs, err := r.recycleTaskIDs(ctx, vm) + if err != nil { + return false, err + } + cutoff := now.Add(-time.Duration(policy.EffectiveRecycleSeconds) * time.Second) + for _, taskID := range taskIDs { + if r.taskLogActivity != nil { + latest, ok, err := r.taskLogActivity.LatestTaskLogTime(ctx, taskID) + if err != nil { + return false, fmt.Errorf("get latest task log time for task %s: %w", taskID, err) + } + if ok && latest.After(cutoff) { + return r.skipRecycleAndRecordActivity(ctx, vm, taskID, latest, cutoff, "clickhouse_task_log") + } + } + + task, err := r.taskRepo.GetByID(ctx, taskID) + if err != nil { + if db.IsNotFound(err) { + continue + } + return false, fmt.Errorf("get task %s before vm recycle: %w", taskID, err) + } + if task.LastActiveAt.After(cutoff) { + return r.skipRecycleAndRecordActivity(ctx, vm, taskID, task.LastActiveAt, cutoff, "pg_task_last_active_at") + } + } + return false, nil +} + +func (r *vmIdleRefresher) skipRecycleAndRecordActivity(ctx context.Context, vm *db.VirtualMachine, taskID uuid.UUID, activeAt, cutoff time.Time, source string) (bool, error) { + r.logger.InfoContext(ctx, "skip vm recycle because task has recent activity", + "vm_id", vm.ID, + "task_id", taskID, + "source", source, + "active_at", activeAt.UTC().Format(time.RFC3339Nano), + "cutoff", cutoff.UTC().Format(time.RFC3339Nano)) + if err := r.applyRefresh(ctx, vm, vmIdleActivityMode); err != nil { + return false, fmt.Errorf("record vm activity after recent task activity: %w", err) + } + return true, nil +} + +func (r *vmIdleRefresher) recycleTaskIDs(ctx context.Context, vm *db.VirtualMachine) ([]uuid.UUID, error) { + seen := make(map[uuid.UUID]struct{}, len(vm.Edges.Tasks)) + taskIDs := make([]uuid.UUID, 0, len(vm.Edges.Tasks)) + for _, task := range vm.Edges.Tasks { + if task == nil { + continue + } + if _, ok := seen[task.ID]; ok { + continue + } + seen[task.ID] = struct{}{} + taskIDs = append(taskIDs, task.ID) + } + if len(vm.Edges.Tasks) > 0 { + return taskIDs, nil + } + + taskIDText, err := r.hostRepo.GetTaskIDByVMID(ctx, vm.ID) + if err != nil { + return nil, fmt.Errorf("get task id by vm %s: %w", vm.ID, err) + } + if taskIDText == "" { + return nil, nil + } + taskID, err := uuid.Parse(taskIDText) + if err != nil { + return nil, fmt.Errorf("invalid task id %q: %w", taskIDText, err) + } + return []uuid.UUID{taskID}, nil +} + +func vmTaskIDs(vm *db.VirtualMachine) []uuid.UUID { + ids := make([]uuid.UUID, 0, len(vm.Edges.Tasks)) + for _, task := range vm.Edges.Tasks { + if task != nil { + ids = append(ids, task.ID) + } + } + return ids +} + func (r *vmIdleRefresher) buildRecycleNotifyEvent(ctx context.Context, vm *db.VirtualMachine, expiresAt time.Time) (*domain.NotifyEvent, error) { // 直接按 virtualmachine_id 查 task_virtualmachines 拿 task_id, // 不再依赖 vm.Edges.Tasks 的 eager load 链。 diff --git a/backend/consts/host.go b/backend/consts/host.go index ae523d760..e4d265401 100644 --- a/backend/consts/host.go +++ b/backend/consts/host.go @@ -11,6 +11,18 @@ const ( Forever VirtualmachineTTLKind = "forever" ) +type VMRecycleMethod string + +const ( + VMRecycleMethodIdle VMRecycleMethod = "idle" + VMRecycleMethodTaskStop VMRecycleMethod = "task_stop" + VMRecycleMethodTaskDelete VMRecycleMethod = "task_delete" + VMRecycleMethodExpired VMRecycleMethod = "expired" + VMRecycleMethodManualDelete VMRecycleMethod = "manual_delete" + VMRecycleMethodForce VMRecycleMethod = "force" + VMRecycleMethodLifecycle VMRecycleMethod = "lifecycle" +) + type HostStatus string const ( diff --git a/backend/db/client.go b/backend/db/client.go index 77c7e4d36..e0954b34f 100644 --- a/backend/db/client.go +++ b/backend/db/client.go @@ -70,6 +70,7 @@ import ( "github.com/chaitin/MonkeyCode/backend/db/user" "github.com/chaitin/MonkeyCode/backend/db/useridentity" "github.com/chaitin/MonkeyCode/backend/db/virtualmachine" + "github.com/chaitin/MonkeyCode/backend/db/virtualmachinerecyclerecord" stdsql "database/sql" ) @@ -187,6 +188,8 @@ type Client struct { UserIdentity *UserIdentityClient // VirtualMachine is the client for interacting with the VirtualMachine builders. VirtualMachine *VirtualMachineClient + // VirtualMachineRecycleRecord is the client for interacting with the VirtualMachineRecycleRecord builders. + VirtualMachineRecycleRecord *VirtualMachineRecycleRecordClient } // NewClient creates a new client configured with the given options. @@ -252,6 +255,7 @@ func (c *Client) init() { c.User = NewUserClient(c.config) c.UserIdentity = NewUserIdentityClient(c.config) c.VirtualMachine = NewVirtualMachineClient(c.config) + c.VirtualMachineRecycleRecord = NewVirtualMachineRecycleRecordClient(c.config) } type ( @@ -342,62 +346,63 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { cfg := c.config cfg.driver = tx return &Tx{ - ctx: ctx, - config: cfg, - AgentPlugin: NewAgentPluginClient(cfg), - AgentPluginRepo: NewAgentPluginRepoClient(cfg), - AgentPluginVersion: NewAgentPluginVersionClient(cfg), - AgentRule: NewAgentRuleClient(cfg), - AgentRuleVersion: NewAgentRuleVersionClient(cfg), - AgentSkill: NewAgentSkillClient(cfg), - AgentSkillGroupBinding: NewAgentSkillGroupBindingClient(cfg), - AgentSkillRepo: NewAgentSkillRepoClient(cfg), - AgentSkillVersion: NewAgentSkillVersionClient(cfg), - AgentSyncJob: NewAgentSyncJobClient(cfg), - Audit: NewAuditClient(cfg), - GitBot: NewGitBotClient(cfg), - GitBotTask: NewGitBotTaskClient(cfg), - GitBotUser: NewGitBotUserClient(cfg), - GitIdentity: NewGitIdentityClient(cfg), - GitTask: NewGitTaskClient(cfg), - Host: NewHostClient(cfg), - Image: NewImageClient(cfg), - MCPTool: NewMCPToolClient(cfg), - MCPToolCall: NewMCPToolCallClient(cfg), - MCPUpstream: NewMCPUpstreamClient(cfg), - MCPUserToolSetting: NewMCPUserToolSettingClient(cfg), - Model: NewModelClient(cfg), - ModelApiKey: NewModelApiKeyClient(cfg), - ModelPricing: NewModelPricingClient(cfg), - NotifyChannel: NewNotifyChannelClient(cfg), - NotifySendLog: NewNotifySendLogClient(cfg), - NotifySubscription: NewNotifySubscriptionClient(cfg), - Project: NewProjectClient(cfg), - ProjectCollaborator: NewProjectCollaboratorClient(cfg), - ProjectGitBot: NewProjectGitBotClient(cfg), - ProjectIssue: NewProjectIssueClient(cfg), - ProjectIssueComment: NewProjectIssueCommentClient(cfg), - ProjectTask: NewProjectTaskClient(cfg), - Task: NewTaskClient(cfg), - TaskModelSwitch: NewTaskModelSwitchClient(cfg), - TaskUsageStat: NewTaskUsageStatClient(cfg), - TaskVirtualMachine: NewTaskVirtualMachineClient(cfg), - Team: NewTeamClient(cfg), - TeamExtensionImageArchive: NewTeamExtensionImageArchiveClient(cfg), - TeamGroup: NewTeamGroupClient(cfg), - TeamGroupHost: NewTeamGroupHostClient(cfg), - TeamGroupImage: NewTeamGroupImageClient(cfg), - TeamGroupMCPUpstream: NewTeamGroupMCPUpstreamClient(cfg), - TeamGroupMember: NewTeamGroupMemberClient(cfg), - TeamGroupModel: NewTeamGroupModelClient(cfg), - TeamHost: NewTeamHostClient(cfg), - TeamImage: NewTeamImageClient(cfg), - TeamMember: NewTeamMemberClient(cfg), - TeamModel: NewTeamModelClient(cfg), - TeamOIDCConfig: NewTeamOIDCConfigClient(cfg), - User: NewUserClient(cfg), - UserIdentity: NewUserIdentityClient(cfg), - VirtualMachine: NewVirtualMachineClient(cfg), + ctx: ctx, + config: cfg, + AgentPlugin: NewAgentPluginClient(cfg), + AgentPluginRepo: NewAgentPluginRepoClient(cfg), + AgentPluginVersion: NewAgentPluginVersionClient(cfg), + AgentRule: NewAgentRuleClient(cfg), + AgentRuleVersion: NewAgentRuleVersionClient(cfg), + AgentSkill: NewAgentSkillClient(cfg), + AgentSkillGroupBinding: NewAgentSkillGroupBindingClient(cfg), + AgentSkillRepo: NewAgentSkillRepoClient(cfg), + AgentSkillVersion: NewAgentSkillVersionClient(cfg), + AgentSyncJob: NewAgentSyncJobClient(cfg), + Audit: NewAuditClient(cfg), + GitBot: NewGitBotClient(cfg), + GitBotTask: NewGitBotTaskClient(cfg), + GitBotUser: NewGitBotUserClient(cfg), + GitIdentity: NewGitIdentityClient(cfg), + GitTask: NewGitTaskClient(cfg), + Host: NewHostClient(cfg), + Image: NewImageClient(cfg), + MCPTool: NewMCPToolClient(cfg), + MCPToolCall: NewMCPToolCallClient(cfg), + MCPUpstream: NewMCPUpstreamClient(cfg), + MCPUserToolSetting: NewMCPUserToolSettingClient(cfg), + Model: NewModelClient(cfg), + ModelApiKey: NewModelApiKeyClient(cfg), + ModelPricing: NewModelPricingClient(cfg), + NotifyChannel: NewNotifyChannelClient(cfg), + NotifySendLog: NewNotifySendLogClient(cfg), + NotifySubscription: NewNotifySubscriptionClient(cfg), + Project: NewProjectClient(cfg), + ProjectCollaborator: NewProjectCollaboratorClient(cfg), + ProjectGitBot: NewProjectGitBotClient(cfg), + ProjectIssue: NewProjectIssueClient(cfg), + ProjectIssueComment: NewProjectIssueCommentClient(cfg), + ProjectTask: NewProjectTaskClient(cfg), + Task: NewTaskClient(cfg), + TaskModelSwitch: NewTaskModelSwitchClient(cfg), + TaskUsageStat: NewTaskUsageStatClient(cfg), + TaskVirtualMachine: NewTaskVirtualMachineClient(cfg), + Team: NewTeamClient(cfg), + TeamExtensionImageArchive: NewTeamExtensionImageArchiveClient(cfg), + TeamGroup: NewTeamGroupClient(cfg), + TeamGroupHost: NewTeamGroupHostClient(cfg), + TeamGroupImage: NewTeamGroupImageClient(cfg), + TeamGroupMCPUpstream: NewTeamGroupMCPUpstreamClient(cfg), + TeamGroupMember: NewTeamGroupMemberClient(cfg), + TeamGroupModel: NewTeamGroupModelClient(cfg), + TeamHost: NewTeamHostClient(cfg), + TeamImage: NewTeamImageClient(cfg), + TeamMember: NewTeamMemberClient(cfg), + TeamModel: NewTeamModelClient(cfg), + TeamOIDCConfig: NewTeamOIDCConfigClient(cfg), + User: NewUserClient(cfg), + UserIdentity: NewUserIdentityClient(cfg), + VirtualMachine: NewVirtualMachineClient(cfg), + VirtualMachineRecycleRecord: NewVirtualMachineRecycleRecordClient(cfg), }, nil } @@ -415,62 +420,63 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) cfg := c.config cfg.driver = &txDriver{tx: tx, drv: c.driver} return &Tx{ - ctx: ctx, - config: cfg, - AgentPlugin: NewAgentPluginClient(cfg), - AgentPluginRepo: NewAgentPluginRepoClient(cfg), - AgentPluginVersion: NewAgentPluginVersionClient(cfg), - AgentRule: NewAgentRuleClient(cfg), - AgentRuleVersion: NewAgentRuleVersionClient(cfg), - AgentSkill: NewAgentSkillClient(cfg), - AgentSkillGroupBinding: NewAgentSkillGroupBindingClient(cfg), - AgentSkillRepo: NewAgentSkillRepoClient(cfg), - AgentSkillVersion: NewAgentSkillVersionClient(cfg), - AgentSyncJob: NewAgentSyncJobClient(cfg), - Audit: NewAuditClient(cfg), - GitBot: NewGitBotClient(cfg), - GitBotTask: NewGitBotTaskClient(cfg), - GitBotUser: NewGitBotUserClient(cfg), - GitIdentity: NewGitIdentityClient(cfg), - GitTask: NewGitTaskClient(cfg), - Host: NewHostClient(cfg), - Image: NewImageClient(cfg), - MCPTool: NewMCPToolClient(cfg), - MCPToolCall: NewMCPToolCallClient(cfg), - MCPUpstream: NewMCPUpstreamClient(cfg), - MCPUserToolSetting: NewMCPUserToolSettingClient(cfg), - Model: NewModelClient(cfg), - ModelApiKey: NewModelApiKeyClient(cfg), - ModelPricing: NewModelPricingClient(cfg), - NotifyChannel: NewNotifyChannelClient(cfg), - NotifySendLog: NewNotifySendLogClient(cfg), - NotifySubscription: NewNotifySubscriptionClient(cfg), - Project: NewProjectClient(cfg), - ProjectCollaborator: NewProjectCollaboratorClient(cfg), - ProjectGitBot: NewProjectGitBotClient(cfg), - ProjectIssue: NewProjectIssueClient(cfg), - ProjectIssueComment: NewProjectIssueCommentClient(cfg), - ProjectTask: NewProjectTaskClient(cfg), - Task: NewTaskClient(cfg), - TaskModelSwitch: NewTaskModelSwitchClient(cfg), - TaskUsageStat: NewTaskUsageStatClient(cfg), - TaskVirtualMachine: NewTaskVirtualMachineClient(cfg), - Team: NewTeamClient(cfg), - TeamExtensionImageArchive: NewTeamExtensionImageArchiveClient(cfg), - TeamGroup: NewTeamGroupClient(cfg), - TeamGroupHost: NewTeamGroupHostClient(cfg), - TeamGroupImage: NewTeamGroupImageClient(cfg), - TeamGroupMCPUpstream: NewTeamGroupMCPUpstreamClient(cfg), - TeamGroupMember: NewTeamGroupMemberClient(cfg), - TeamGroupModel: NewTeamGroupModelClient(cfg), - TeamHost: NewTeamHostClient(cfg), - TeamImage: NewTeamImageClient(cfg), - TeamMember: NewTeamMemberClient(cfg), - TeamModel: NewTeamModelClient(cfg), - TeamOIDCConfig: NewTeamOIDCConfigClient(cfg), - User: NewUserClient(cfg), - UserIdentity: NewUserIdentityClient(cfg), - VirtualMachine: NewVirtualMachineClient(cfg), + ctx: ctx, + config: cfg, + AgentPlugin: NewAgentPluginClient(cfg), + AgentPluginRepo: NewAgentPluginRepoClient(cfg), + AgentPluginVersion: NewAgentPluginVersionClient(cfg), + AgentRule: NewAgentRuleClient(cfg), + AgentRuleVersion: NewAgentRuleVersionClient(cfg), + AgentSkill: NewAgentSkillClient(cfg), + AgentSkillGroupBinding: NewAgentSkillGroupBindingClient(cfg), + AgentSkillRepo: NewAgentSkillRepoClient(cfg), + AgentSkillVersion: NewAgentSkillVersionClient(cfg), + AgentSyncJob: NewAgentSyncJobClient(cfg), + Audit: NewAuditClient(cfg), + GitBot: NewGitBotClient(cfg), + GitBotTask: NewGitBotTaskClient(cfg), + GitBotUser: NewGitBotUserClient(cfg), + GitIdentity: NewGitIdentityClient(cfg), + GitTask: NewGitTaskClient(cfg), + Host: NewHostClient(cfg), + Image: NewImageClient(cfg), + MCPTool: NewMCPToolClient(cfg), + MCPToolCall: NewMCPToolCallClient(cfg), + MCPUpstream: NewMCPUpstreamClient(cfg), + MCPUserToolSetting: NewMCPUserToolSettingClient(cfg), + Model: NewModelClient(cfg), + ModelApiKey: NewModelApiKeyClient(cfg), + ModelPricing: NewModelPricingClient(cfg), + NotifyChannel: NewNotifyChannelClient(cfg), + NotifySendLog: NewNotifySendLogClient(cfg), + NotifySubscription: NewNotifySubscriptionClient(cfg), + Project: NewProjectClient(cfg), + ProjectCollaborator: NewProjectCollaboratorClient(cfg), + ProjectGitBot: NewProjectGitBotClient(cfg), + ProjectIssue: NewProjectIssueClient(cfg), + ProjectIssueComment: NewProjectIssueCommentClient(cfg), + ProjectTask: NewProjectTaskClient(cfg), + Task: NewTaskClient(cfg), + TaskModelSwitch: NewTaskModelSwitchClient(cfg), + TaskUsageStat: NewTaskUsageStatClient(cfg), + TaskVirtualMachine: NewTaskVirtualMachineClient(cfg), + Team: NewTeamClient(cfg), + TeamExtensionImageArchive: NewTeamExtensionImageArchiveClient(cfg), + TeamGroup: NewTeamGroupClient(cfg), + TeamGroupHost: NewTeamGroupHostClient(cfg), + TeamGroupImage: NewTeamGroupImageClient(cfg), + TeamGroupMCPUpstream: NewTeamGroupMCPUpstreamClient(cfg), + TeamGroupMember: NewTeamGroupMemberClient(cfg), + TeamGroupModel: NewTeamGroupModelClient(cfg), + TeamHost: NewTeamHostClient(cfg), + TeamImage: NewTeamImageClient(cfg), + TeamMember: NewTeamMemberClient(cfg), + TeamModel: NewTeamModelClient(cfg), + TeamOIDCConfig: NewTeamOIDCConfigClient(cfg), + User: NewUserClient(cfg), + UserIdentity: NewUserIdentityClient(cfg), + VirtualMachine: NewVirtualMachineClient(cfg), + VirtualMachineRecycleRecord: NewVirtualMachineRecycleRecordClient(cfg), }, nil } @@ -512,6 +518,7 @@ func (c *Client) Use(hooks ...Hook) { c.TeamGroup, c.TeamGroupHost, c.TeamGroupImage, c.TeamGroupMCPUpstream, c.TeamGroupMember, c.TeamGroupModel, c.TeamHost, c.TeamImage, c.TeamMember, c.TeamModel, c.TeamOIDCConfig, c.User, c.UserIdentity, c.VirtualMachine, + c.VirtualMachineRecycleRecord, } { n.Use(hooks...) } @@ -533,6 +540,7 @@ func (c *Client) Intercept(interceptors ...Interceptor) { c.TeamGroup, c.TeamGroupHost, c.TeamGroupImage, c.TeamGroupMCPUpstream, c.TeamGroupMember, c.TeamGroupModel, c.TeamHost, c.TeamImage, c.TeamMember, c.TeamModel, c.TeamOIDCConfig, c.User, c.UserIdentity, c.VirtualMachine, + c.VirtualMachineRecycleRecord, } { n.Intercept(interceptors...) } @@ -649,6 +657,8 @@ func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) { return c.UserIdentity.mutate(ctx, m) case *VirtualMachineMutation: return c.VirtualMachine.mutate(ctx, m) + case *VirtualMachineRecycleRecordMutation: + return c.VirtualMachineRecycleRecord.mutate(ctx, m) default: return nil, fmt.Errorf("db: unknown mutation type %T", m) } @@ -10660,6 +10670,139 @@ func (c *VirtualMachineClient) mutate(ctx context.Context, m *VirtualMachineMuta } } +// VirtualMachineRecycleRecordClient is a client for the VirtualMachineRecycleRecord schema. +type VirtualMachineRecycleRecordClient struct { + config +} + +// NewVirtualMachineRecycleRecordClient returns a client for the VirtualMachineRecycleRecord from the given config. +func NewVirtualMachineRecycleRecordClient(c config) *VirtualMachineRecycleRecordClient { + return &VirtualMachineRecycleRecordClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `virtualmachinerecyclerecord.Hooks(f(g(h())))`. +func (c *VirtualMachineRecycleRecordClient) Use(hooks ...Hook) { + c.hooks.VirtualMachineRecycleRecord = append(c.hooks.VirtualMachineRecycleRecord, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `virtualmachinerecyclerecord.Intercept(f(g(h())))`. +func (c *VirtualMachineRecycleRecordClient) Intercept(interceptors ...Interceptor) { + c.inters.VirtualMachineRecycleRecord = append(c.inters.VirtualMachineRecycleRecord, interceptors...) +} + +// Create returns a builder for creating a VirtualMachineRecycleRecord entity. +func (c *VirtualMachineRecycleRecordClient) Create() *VirtualMachineRecycleRecordCreate { + mutation := newVirtualMachineRecycleRecordMutation(c.config, OpCreate) + return &VirtualMachineRecycleRecordCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of VirtualMachineRecycleRecord entities. +func (c *VirtualMachineRecycleRecordClient) CreateBulk(builders ...*VirtualMachineRecycleRecordCreate) *VirtualMachineRecycleRecordCreateBulk { + return &VirtualMachineRecycleRecordCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *VirtualMachineRecycleRecordClient) MapCreateBulk(slice any, setFunc func(*VirtualMachineRecycleRecordCreate, int)) *VirtualMachineRecycleRecordCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &VirtualMachineRecycleRecordCreateBulk{err: fmt.Errorf("calling to VirtualMachineRecycleRecordClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*VirtualMachineRecycleRecordCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &VirtualMachineRecycleRecordCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for VirtualMachineRecycleRecord. +func (c *VirtualMachineRecycleRecordClient) Update() *VirtualMachineRecycleRecordUpdate { + mutation := newVirtualMachineRecycleRecordMutation(c.config, OpUpdate) + return &VirtualMachineRecycleRecordUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *VirtualMachineRecycleRecordClient) UpdateOne(_m *VirtualMachineRecycleRecord) *VirtualMachineRecycleRecordUpdateOne { + mutation := newVirtualMachineRecycleRecordMutation(c.config, OpUpdateOne, withVirtualMachineRecycleRecord(_m)) + return &VirtualMachineRecycleRecordUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *VirtualMachineRecycleRecordClient) UpdateOneID(id uuid.UUID) *VirtualMachineRecycleRecordUpdateOne { + mutation := newVirtualMachineRecycleRecordMutation(c.config, OpUpdateOne, withVirtualMachineRecycleRecordID(id)) + return &VirtualMachineRecycleRecordUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for VirtualMachineRecycleRecord. +func (c *VirtualMachineRecycleRecordClient) Delete() *VirtualMachineRecycleRecordDelete { + mutation := newVirtualMachineRecycleRecordMutation(c.config, OpDelete) + return &VirtualMachineRecycleRecordDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *VirtualMachineRecycleRecordClient) DeleteOne(_m *VirtualMachineRecycleRecord) *VirtualMachineRecycleRecordDeleteOne { + return c.DeleteOneID(_m.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *VirtualMachineRecycleRecordClient) DeleteOneID(id uuid.UUID) *VirtualMachineRecycleRecordDeleteOne { + builder := c.Delete().Where(virtualmachinerecyclerecord.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &VirtualMachineRecycleRecordDeleteOne{builder} +} + +// Query returns a query builder for VirtualMachineRecycleRecord. +func (c *VirtualMachineRecycleRecordClient) Query() *VirtualMachineRecycleRecordQuery { + return &VirtualMachineRecycleRecordQuery{ + config: c.config, + ctx: &QueryContext{Type: TypeVirtualMachineRecycleRecord}, + inters: c.Interceptors(), + } +} + +// Get returns a VirtualMachineRecycleRecord entity by its id. +func (c *VirtualMachineRecycleRecordClient) Get(ctx context.Context, id uuid.UUID) (*VirtualMachineRecycleRecord, error) { + return c.Query().Where(virtualmachinerecyclerecord.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *VirtualMachineRecycleRecordClient) GetX(ctx context.Context, id uuid.UUID) *VirtualMachineRecycleRecord { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// Hooks returns the client hooks. +func (c *VirtualMachineRecycleRecordClient) Hooks() []Hook { + return c.hooks.VirtualMachineRecycleRecord +} + +// Interceptors returns the client interceptors. +func (c *VirtualMachineRecycleRecordClient) Interceptors() []Interceptor { + return c.inters.VirtualMachineRecycleRecord +} + +func (c *VirtualMachineRecycleRecordClient) mutate(ctx context.Context, m *VirtualMachineRecycleRecordMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&VirtualMachineRecycleRecordCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&VirtualMachineRecycleRecordUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&VirtualMachineRecycleRecordUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&VirtualMachineRecycleRecordDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("db: unknown VirtualMachineRecycleRecord mutation op: %q", m.Op()) + } +} + // hooks and interceptors per client, for fast access. type ( hooks struct { @@ -10672,8 +10815,8 @@ type ( ProjectTask, Task, TaskModelSwitch, TaskUsageStat, TaskVirtualMachine, Team, TeamExtensionImageArchive, TeamGroup, TeamGroupHost, TeamGroupImage, TeamGroupMCPUpstream, TeamGroupMember, TeamGroupModel, TeamHost, TeamImage, - TeamMember, TeamModel, TeamOIDCConfig, User, UserIdentity, - VirtualMachine []ent.Hook + TeamMember, TeamModel, TeamOIDCConfig, User, UserIdentity, VirtualMachine, + VirtualMachineRecycleRecord []ent.Hook } inters struct { AgentPlugin, AgentPluginRepo, AgentPluginVersion, AgentRule, AgentRuleVersion, @@ -10685,8 +10828,8 @@ type ( ProjectTask, Task, TaskModelSwitch, TaskUsageStat, TaskVirtualMachine, Team, TeamExtensionImageArchive, TeamGroup, TeamGroupHost, TeamGroupImage, TeamGroupMCPUpstream, TeamGroupMember, TeamGroupModel, TeamHost, TeamImage, - TeamMember, TeamModel, TeamOIDCConfig, User, UserIdentity, - VirtualMachine []ent.Interceptor + TeamMember, TeamModel, TeamOIDCConfig, User, UserIdentity, VirtualMachine, + VirtualMachineRecycleRecord []ent.Interceptor } ) diff --git a/backend/db/ent.go b/backend/db/ent.go index 983c36150..4738d5d47 100644 --- a/backend/db/ent.go +++ b/backend/db/ent.go @@ -66,6 +66,7 @@ import ( "github.com/chaitin/MonkeyCode/backend/db/user" "github.com/chaitin/MonkeyCode/backend/db/useridentity" "github.com/chaitin/MonkeyCode/backend/db/virtualmachine" + "github.com/chaitin/MonkeyCode/backend/db/virtualmachinerecyclerecord" ) // ent aliases to avoid import conflicts in user's code. @@ -126,60 +127,61 @@ var ( func checkColumn(t, c string) error { initCheck.Do(func() { columnCheck = sql.NewColumnCheck(map[string]func(string) bool{ - agentplugin.Table: agentplugin.ValidColumn, - agentpluginrepo.Table: agentpluginrepo.ValidColumn, - agentpluginversion.Table: agentpluginversion.ValidColumn, - agentrule.Table: agentrule.ValidColumn, - agentruleversion.Table: agentruleversion.ValidColumn, - agentskill.Table: agentskill.ValidColumn, - agentskillgroupbinding.Table: agentskillgroupbinding.ValidColumn, - agentskillrepo.Table: agentskillrepo.ValidColumn, - agentskillversion.Table: agentskillversion.ValidColumn, - agentsyncjob.Table: agentsyncjob.ValidColumn, - audit.Table: audit.ValidColumn, - gitbot.Table: gitbot.ValidColumn, - gitbottask.Table: gitbottask.ValidColumn, - gitbotuser.Table: gitbotuser.ValidColumn, - gitidentity.Table: gitidentity.ValidColumn, - gittask.Table: gittask.ValidColumn, - host.Table: host.ValidColumn, - image.Table: image.ValidColumn, - mcptool.Table: mcptool.ValidColumn, - mcptoolcall.Table: mcptoolcall.ValidColumn, - mcpupstream.Table: mcpupstream.ValidColumn, - mcpusertoolsetting.Table: mcpusertoolsetting.ValidColumn, - model.Table: model.ValidColumn, - modelapikey.Table: modelapikey.ValidColumn, - modelpricing.Table: modelpricing.ValidColumn, - notifychannel.Table: notifychannel.ValidColumn, - notifysendlog.Table: notifysendlog.ValidColumn, - notifysubscription.Table: notifysubscription.ValidColumn, - project.Table: project.ValidColumn, - projectcollaborator.Table: projectcollaborator.ValidColumn, - projectgitbot.Table: projectgitbot.ValidColumn, - projectissue.Table: projectissue.ValidColumn, - projectissuecomment.Table: projectissuecomment.ValidColumn, - projecttask.Table: projecttask.ValidColumn, - task.Table: task.ValidColumn, - taskmodelswitch.Table: taskmodelswitch.ValidColumn, - taskusagestat.Table: taskusagestat.ValidColumn, - taskvirtualmachine.Table: taskvirtualmachine.ValidColumn, - team.Table: team.ValidColumn, - teamextensionimagearchive.Table: teamextensionimagearchive.ValidColumn, - teamgroup.Table: teamgroup.ValidColumn, - teamgrouphost.Table: teamgrouphost.ValidColumn, - teamgroupimage.Table: teamgroupimage.ValidColumn, - teamgroupmcpupstream.Table: teamgroupmcpupstream.ValidColumn, - teamgroupmember.Table: teamgroupmember.ValidColumn, - teamgroupmodel.Table: teamgroupmodel.ValidColumn, - teamhost.Table: teamhost.ValidColumn, - teamimage.Table: teamimage.ValidColumn, - teammember.Table: teammember.ValidColumn, - teammodel.Table: teammodel.ValidColumn, - teamoidcconfig.Table: teamoidcconfig.ValidColumn, - user.Table: user.ValidColumn, - useridentity.Table: useridentity.ValidColumn, - virtualmachine.Table: virtualmachine.ValidColumn, + agentplugin.Table: agentplugin.ValidColumn, + agentpluginrepo.Table: agentpluginrepo.ValidColumn, + agentpluginversion.Table: agentpluginversion.ValidColumn, + agentrule.Table: agentrule.ValidColumn, + agentruleversion.Table: agentruleversion.ValidColumn, + agentskill.Table: agentskill.ValidColumn, + agentskillgroupbinding.Table: agentskillgroupbinding.ValidColumn, + agentskillrepo.Table: agentskillrepo.ValidColumn, + agentskillversion.Table: agentskillversion.ValidColumn, + agentsyncjob.Table: agentsyncjob.ValidColumn, + audit.Table: audit.ValidColumn, + gitbot.Table: gitbot.ValidColumn, + gitbottask.Table: gitbottask.ValidColumn, + gitbotuser.Table: gitbotuser.ValidColumn, + gitidentity.Table: gitidentity.ValidColumn, + gittask.Table: gittask.ValidColumn, + host.Table: host.ValidColumn, + image.Table: image.ValidColumn, + mcptool.Table: mcptool.ValidColumn, + mcptoolcall.Table: mcptoolcall.ValidColumn, + mcpupstream.Table: mcpupstream.ValidColumn, + mcpusertoolsetting.Table: mcpusertoolsetting.ValidColumn, + model.Table: model.ValidColumn, + modelapikey.Table: modelapikey.ValidColumn, + modelpricing.Table: modelpricing.ValidColumn, + notifychannel.Table: notifychannel.ValidColumn, + notifysendlog.Table: notifysendlog.ValidColumn, + notifysubscription.Table: notifysubscription.ValidColumn, + project.Table: project.ValidColumn, + projectcollaborator.Table: projectcollaborator.ValidColumn, + projectgitbot.Table: projectgitbot.ValidColumn, + projectissue.Table: projectissue.ValidColumn, + projectissuecomment.Table: projectissuecomment.ValidColumn, + projecttask.Table: projecttask.ValidColumn, + task.Table: task.ValidColumn, + taskmodelswitch.Table: taskmodelswitch.ValidColumn, + taskusagestat.Table: taskusagestat.ValidColumn, + taskvirtualmachine.Table: taskvirtualmachine.ValidColumn, + team.Table: team.ValidColumn, + teamextensionimagearchive.Table: teamextensionimagearchive.ValidColumn, + teamgroup.Table: teamgroup.ValidColumn, + teamgrouphost.Table: teamgrouphost.ValidColumn, + teamgroupimage.Table: teamgroupimage.ValidColumn, + teamgroupmcpupstream.Table: teamgroupmcpupstream.ValidColumn, + teamgroupmember.Table: teamgroupmember.ValidColumn, + teamgroupmodel.Table: teamgroupmodel.ValidColumn, + teamhost.Table: teamhost.ValidColumn, + teamimage.Table: teamimage.ValidColumn, + teammember.Table: teammember.ValidColumn, + teammodel.Table: teammodel.ValidColumn, + teamoidcconfig.Table: teamoidcconfig.ValidColumn, + user.Table: user.ValidColumn, + useridentity.Table: useridentity.ValidColumn, + virtualmachine.Table: virtualmachine.ValidColumn, + virtualmachinerecyclerecord.Table: virtualmachinerecyclerecord.ValidColumn, }) }) return columnCheck(t, c) diff --git a/backend/db/hook/hook.go b/backend/db/hook/hook.go index 1ee877d7b..ec6068829 100644 --- a/backend/db/hook/hook.go +++ b/backend/db/hook/hook.go @@ -657,6 +657,18 @@ func (f VirtualMachineFunc) Mutate(ctx context.Context, m db.Mutation) (db.Value return nil, fmt.Errorf("unexpected mutation type %T. expect *db.VirtualMachineMutation", m) } +// The VirtualMachineRecycleRecordFunc type is an adapter to allow the use of ordinary +// function as VirtualMachineRecycleRecord mutator. +type VirtualMachineRecycleRecordFunc func(context.Context, *db.VirtualMachineRecycleRecordMutation) (db.Value, error) + +// Mutate calls f(ctx, m). +func (f VirtualMachineRecycleRecordFunc) Mutate(ctx context.Context, m db.Mutation) (db.Value, error) { + if mv, ok := m.(*db.VirtualMachineRecycleRecordMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *db.VirtualMachineRecycleRecordMutation", m) +} + // Condition is a hook condition function. type Condition func(context.Context, db.Mutation) bool diff --git a/backend/db/intercept/intercept.go b/backend/db/intercept/intercept.go index dcc92c0b6..f5806a71d 100644 --- a/backend/db/intercept/intercept.go +++ b/backend/db/intercept/intercept.go @@ -63,6 +63,7 @@ import ( "github.com/chaitin/MonkeyCode/backend/db/user" "github.com/chaitin/MonkeyCode/backend/db/useridentity" "github.com/chaitin/MonkeyCode/backend/db/virtualmachine" + "github.com/chaitin/MonkeyCode/backend/db/virtualmachinerecyclerecord" ) // The Query interface represents an operation that queries a graph. @@ -1579,6 +1580,33 @@ func (f TraverseVirtualMachine) Traverse(ctx context.Context, q db.Query) error return fmt.Errorf("unexpected query type %T. expect *db.VirtualMachineQuery", q) } +// The VirtualMachineRecycleRecordFunc type is an adapter to allow the use of ordinary function as a Querier. +type VirtualMachineRecycleRecordFunc func(context.Context, *db.VirtualMachineRecycleRecordQuery) (db.Value, error) + +// Query calls f(ctx, q). +func (f VirtualMachineRecycleRecordFunc) Query(ctx context.Context, q db.Query) (db.Value, error) { + if q, ok := q.(*db.VirtualMachineRecycleRecordQuery); ok { + return f(ctx, q) + } + return nil, fmt.Errorf("unexpected query type %T. expect *db.VirtualMachineRecycleRecordQuery", q) +} + +// The TraverseVirtualMachineRecycleRecord type is an adapter to allow the use of ordinary function as Traverser. +type TraverseVirtualMachineRecycleRecord func(context.Context, *db.VirtualMachineRecycleRecordQuery) error + +// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline. +func (f TraverseVirtualMachineRecycleRecord) Intercept(next db.Querier) db.Querier { + return next +} + +// Traverse calls f(ctx, q). +func (f TraverseVirtualMachineRecycleRecord) Traverse(ctx context.Context, q db.Query) error { + if q, ok := q.(*db.VirtualMachineRecycleRecordQuery); ok { + return f(ctx, q) + } + return fmt.Errorf("unexpected query type %T. expect *db.VirtualMachineRecycleRecordQuery", q) +} + // NewQuery returns the generic Query interface for the given typed query. func NewQuery(q db.Query) (Query, error) { switch q := q.(type) { @@ -1690,6 +1718,8 @@ func NewQuery(q db.Query) (Query, error) { return &query[*db.UserIdentityQuery, predicate.UserIdentity, useridentity.OrderOption]{typ: db.TypeUserIdentity, tq: q}, nil case *db.VirtualMachineQuery: return &query[*db.VirtualMachineQuery, predicate.VirtualMachine, virtualmachine.OrderOption]{typ: db.TypeVirtualMachine, tq: q}, nil + case *db.VirtualMachineRecycleRecordQuery: + return &query[*db.VirtualMachineRecycleRecordQuery, predicate.VirtualMachineRecycleRecord, virtualmachinerecyclerecord.OrderOption]{typ: db.TypeVirtualMachineRecycleRecord, tq: q}, nil default: return nil, fmt.Errorf("unknown query type %T", q) } diff --git a/backend/db/migrate/schema.go b/backend/db/migrate/schema.go index aa0ca026d..59a5b2211 100644 --- a/backend/db/migrate/schema.go +++ b/backend/db/migrate/schema.go @@ -1962,6 +1962,37 @@ var ( }, }, } + // VirtualmachineRecycleRecordsColumns holds the columns for the "virtualmachine_recycle_records" table. + VirtualmachineRecycleRecordsColumns = []*schema.Column{ + {Name: "id", Type: field.TypeUUID, Unique: true}, + {Name: "virtualmachine_id", Type: field.TypeString, Unique: true}, + {Name: "environment_id", Type: field.TypeString}, + {Name: "host_id", Type: field.TypeString}, + {Name: "user_id", Type: field.TypeUUID, Nullable: true}, + {Name: "task_ids", Type: field.TypeJSON}, + {Name: "method", Type: field.TypeString}, + {Name: "remote_deleted", Type: field.TypeBool, Default: false}, + {Name: "recycled_at", Type: field.TypeTime}, + {Name: "created_at", Type: field.TypeTime}, + } + // VirtualmachineRecycleRecordsTable holds the schema information for the "virtualmachine_recycle_records" table. + VirtualmachineRecycleRecordsTable = &schema.Table{ + Name: "virtualmachine_recycle_records", + Columns: VirtualmachineRecycleRecordsColumns, + PrimaryKey: []*schema.Column{VirtualmachineRecycleRecordsColumns[0]}, + Indexes: []*schema.Index{ + { + Name: "virtualmachinerecyclerecord_method_recycled_at", + Unique: false, + Columns: []*schema.Column{VirtualmachineRecycleRecordsColumns[6], VirtualmachineRecycleRecordsColumns[8]}, + }, + { + Name: "virtualmachinerecyclerecord_user_id_recycled_at", + Unique: false, + Columns: []*schema.Column{VirtualmachineRecycleRecordsColumns[4], VirtualmachineRecycleRecordsColumns[8]}, + }, + }, + } // Tables holds all the tables in the schema. Tables = []*schema.Table{ AgentPluginsTable, @@ -2018,6 +2049,7 @@ var ( UsersTable, UserIdentitiesTable, VirtualmachinesTable, + VirtualmachineRecycleRecordsTable, } ) @@ -2264,4 +2296,7 @@ func init() { VirtualmachinesTable.Annotation = &entsql.Annotation{ Table: "virtualmachines", } + VirtualmachineRecycleRecordsTable.Annotation = &entsql.Annotation{ + Table: "virtualmachine_recycle_records", + } } diff --git a/backend/db/mutation.go b/backend/db/mutation.go index 3130e1293..bcaaf75a5 100644 --- a/backend/db/mutation.go +++ b/backend/db/mutation.go @@ -67,6 +67,7 @@ import ( "github.com/chaitin/MonkeyCode/backend/db/user" "github.com/chaitin/MonkeyCode/backend/db/useridentity" "github.com/chaitin/MonkeyCode/backend/db/virtualmachine" + "github.com/chaitin/MonkeyCode/backend/db/virtualmachinerecyclerecord" "github.com/chaitin/MonkeyCode/backend/ent/types" "github.com/google/uuid" ) @@ -80,60 +81,61 @@ const ( OpUpdateOne = ent.OpUpdateOne // Node types. - TypeAgentPlugin = "AgentPlugin" - TypeAgentPluginRepo = "AgentPluginRepo" - TypeAgentPluginVersion = "AgentPluginVersion" - TypeAgentRule = "AgentRule" - TypeAgentRuleVersion = "AgentRuleVersion" - TypeAgentSkill = "AgentSkill" - TypeAgentSkillGroupBinding = "AgentSkillGroupBinding" - TypeAgentSkillRepo = "AgentSkillRepo" - TypeAgentSkillVersion = "AgentSkillVersion" - TypeAgentSyncJob = "AgentSyncJob" - TypeAudit = "Audit" - TypeGitBot = "GitBot" - TypeGitBotTask = "GitBotTask" - TypeGitBotUser = "GitBotUser" - TypeGitIdentity = "GitIdentity" - TypeGitTask = "GitTask" - TypeHost = "Host" - TypeImage = "Image" - TypeMCPTool = "MCPTool" - TypeMCPToolCall = "MCPToolCall" - TypeMCPUpstream = "MCPUpstream" - TypeMCPUserToolSetting = "MCPUserToolSetting" - TypeModel = "Model" - TypeModelApiKey = "ModelApiKey" - TypeModelPricing = "ModelPricing" - TypeNotifyChannel = "NotifyChannel" - TypeNotifySendLog = "NotifySendLog" - TypeNotifySubscription = "NotifySubscription" - TypeProject = "Project" - TypeProjectCollaborator = "ProjectCollaborator" - TypeProjectGitBot = "ProjectGitBot" - TypeProjectIssue = "ProjectIssue" - TypeProjectIssueComment = "ProjectIssueComment" - TypeProjectTask = "ProjectTask" - TypeTask = "Task" - TypeTaskModelSwitch = "TaskModelSwitch" - TypeTaskUsageStat = "TaskUsageStat" - TypeTaskVirtualMachine = "TaskVirtualMachine" - TypeTeam = "Team" - TypeTeamExtensionImageArchive = "TeamExtensionImageArchive" - TypeTeamGroup = "TeamGroup" - TypeTeamGroupHost = "TeamGroupHost" - TypeTeamGroupImage = "TeamGroupImage" - TypeTeamGroupMCPUpstream = "TeamGroupMCPUpstream" - TypeTeamGroupMember = "TeamGroupMember" - TypeTeamGroupModel = "TeamGroupModel" - TypeTeamHost = "TeamHost" - TypeTeamImage = "TeamImage" - TypeTeamMember = "TeamMember" - TypeTeamModel = "TeamModel" - TypeTeamOIDCConfig = "TeamOIDCConfig" - TypeUser = "User" - TypeUserIdentity = "UserIdentity" - TypeVirtualMachine = "VirtualMachine" + TypeAgentPlugin = "AgentPlugin" + TypeAgentPluginRepo = "AgentPluginRepo" + TypeAgentPluginVersion = "AgentPluginVersion" + TypeAgentRule = "AgentRule" + TypeAgentRuleVersion = "AgentRuleVersion" + TypeAgentSkill = "AgentSkill" + TypeAgentSkillGroupBinding = "AgentSkillGroupBinding" + TypeAgentSkillRepo = "AgentSkillRepo" + TypeAgentSkillVersion = "AgentSkillVersion" + TypeAgentSyncJob = "AgentSyncJob" + TypeAudit = "Audit" + TypeGitBot = "GitBot" + TypeGitBotTask = "GitBotTask" + TypeGitBotUser = "GitBotUser" + TypeGitIdentity = "GitIdentity" + TypeGitTask = "GitTask" + TypeHost = "Host" + TypeImage = "Image" + TypeMCPTool = "MCPTool" + TypeMCPToolCall = "MCPToolCall" + TypeMCPUpstream = "MCPUpstream" + TypeMCPUserToolSetting = "MCPUserToolSetting" + TypeModel = "Model" + TypeModelApiKey = "ModelApiKey" + TypeModelPricing = "ModelPricing" + TypeNotifyChannel = "NotifyChannel" + TypeNotifySendLog = "NotifySendLog" + TypeNotifySubscription = "NotifySubscription" + TypeProject = "Project" + TypeProjectCollaborator = "ProjectCollaborator" + TypeProjectGitBot = "ProjectGitBot" + TypeProjectIssue = "ProjectIssue" + TypeProjectIssueComment = "ProjectIssueComment" + TypeProjectTask = "ProjectTask" + TypeTask = "Task" + TypeTaskModelSwitch = "TaskModelSwitch" + TypeTaskUsageStat = "TaskUsageStat" + TypeTaskVirtualMachine = "TaskVirtualMachine" + TypeTeam = "Team" + TypeTeamExtensionImageArchive = "TeamExtensionImageArchive" + TypeTeamGroup = "TeamGroup" + TypeTeamGroupHost = "TeamGroupHost" + TypeTeamGroupImage = "TeamGroupImage" + TypeTeamGroupMCPUpstream = "TeamGroupMCPUpstream" + TypeTeamGroupMember = "TeamGroupMember" + TypeTeamGroupModel = "TeamGroupModel" + TypeTeamHost = "TeamHost" + TypeTeamImage = "TeamImage" + TypeTeamMember = "TeamMember" + TypeTeamModel = "TeamModel" + TypeTeamOIDCConfig = "TeamOIDCConfig" + TypeUser = "User" + TypeUserIdentity = "UserIdentity" + TypeVirtualMachine = "VirtualMachine" + TypeVirtualMachineRecycleRecord = "VirtualMachineRecycleRecord" ) // AgentPluginMutation represents an operation that mutates the AgentPlugin nodes in the graph. @@ -57927,3 +57929,805 @@ func (m *VirtualMachineMutation) ResetEdge(name string) error { } return fmt.Errorf("unknown VirtualMachine edge %s", name) } + +// VirtualMachineRecycleRecordMutation represents an operation that mutates the VirtualMachineRecycleRecord nodes in the graph. +type VirtualMachineRecycleRecordMutation struct { + config + op Op + typ string + id *uuid.UUID + virtualmachine_id *string + environment_id *string + host_id *string + user_id *uuid.UUID + task_ids *[]uuid.UUID + appendtask_ids []uuid.UUID + method *consts.VMRecycleMethod + remote_deleted *bool + recycled_at *time.Time + created_at *time.Time + clearedFields map[string]struct{} + done bool + oldValue func(context.Context) (*VirtualMachineRecycleRecord, error) + predicates []predicate.VirtualMachineRecycleRecord +} + +var _ ent.Mutation = (*VirtualMachineRecycleRecordMutation)(nil) + +// virtualmachinerecyclerecordOption allows management of the mutation configuration using functional options. +type virtualmachinerecyclerecordOption func(*VirtualMachineRecycleRecordMutation) + +// newVirtualMachineRecycleRecordMutation creates new mutation for the VirtualMachineRecycleRecord entity. +func newVirtualMachineRecycleRecordMutation(c config, op Op, opts ...virtualmachinerecyclerecordOption) *VirtualMachineRecycleRecordMutation { + m := &VirtualMachineRecycleRecordMutation{ + config: c, + op: op, + typ: TypeVirtualMachineRecycleRecord, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withVirtualMachineRecycleRecordID sets the ID field of the mutation. +func withVirtualMachineRecycleRecordID(id uuid.UUID) virtualmachinerecyclerecordOption { + return func(m *VirtualMachineRecycleRecordMutation) { + var ( + err error + once sync.Once + value *VirtualMachineRecycleRecord + ) + m.oldValue = func(ctx context.Context) (*VirtualMachineRecycleRecord, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().VirtualMachineRecycleRecord.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withVirtualMachineRecycleRecord sets the old VirtualMachineRecycleRecord of the mutation. +func withVirtualMachineRecycleRecord(node *VirtualMachineRecycleRecord) virtualmachinerecyclerecordOption { + return func(m *VirtualMachineRecycleRecordMutation) { + m.oldValue = func(context.Context) (*VirtualMachineRecycleRecord, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m VirtualMachineRecycleRecordMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m VirtualMachineRecycleRecordMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("db: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// SetID sets the value of the id field. Note that this +// operation is only accepted on creation of VirtualMachineRecycleRecord entities. +func (m *VirtualMachineRecycleRecordMutation) SetID(id uuid.UUID) { + m.id = &id +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *VirtualMachineRecycleRecordMutation) ID() (id uuid.UUID, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *VirtualMachineRecycleRecordMutation) IDs(ctx context.Context) ([]uuid.UUID, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []uuid.UUID{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().VirtualMachineRecycleRecord.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetVirtualmachineID sets the "virtualmachine_id" field. +func (m *VirtualMachineRecycleRecordMutation) SetVirtualmachineID(s string) { + m.virtualmachine_id = &s +} + +// VirtualmachineID returns the value of the "virtualmachine_id" field in the mutation. +func (m *VirtualMachineRecycleRecordMutation) VirtualmachineID() (r string, exists bool) { + v := m.virtualmachine_id + if v == nil { + return + } + return *v, true +} + +// OldVirtualmachineID returns the old "virtualmachine_id" field's value of the VirtualMachineRecycleRecord entity. +// If the VirtualMachineRecycleRecord object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *VirtualMachineRecycleRecordMutation) OldVirtualmachineID(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldVirtualmachineID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldVirtualmachineID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldVirtualmachineID: %w", err) + } + return oldValue.VirtualmachineID, nil +} + +// ResetVirtualmachineID resets all changes to the "virtualmachine_id" field. +func (m *VirtualMachineRecycleRecordMutation) ResetVirtualmachineID() { + m.virtualmachine_id = nil +} + +// SetEnvironmentID sets the "environment_id" field. +func (m *VirtualMachineRecycleRecordMutation) SetEnvironmentID(s string) { + m.environment_id = &s +} + +// EnvironmentID returns the value of the "environment_id" field in the mutation. +func (m *VirtualMachineRecycleRecordMutation) EnvironmentID() (r string, exists bool) { + v := m.environment_id + if v == nil { + return + } + return *v, true +} + +// OldEnvironmentID returns the old "environment_id" field's value of the VirtualMachineRecycleRecord entity. +// If the VirtualMachineRecycleRecord object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *VirtualMachineRecycleRecordMutation) OldEnvironmentID(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldEnvironmentID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldEnvironmentID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldEnvironmentID: %w", err) + } + return oldValue.EnvironmentID, nil +} + +// ResetEnvironmentID resets all changes to the "environment_id" field. +func (m *VirtualMachineRecycleRecordMutation) ResetEnvironmentID() { + m.environment_id = nil +} + +// SetHostID sets the "host_id" field. +func (m *VirtualMachineRecycleRecordMutation) SetHostID(s string) { + m.host_id = &s +} + +// HostID returns the value of the "host_id" field in the mutation. +func (m *VirtualMachineRecycleRecordMutation) HostID() (r string, exists bool) { + v := m.host_id + if v == nil { + return + } + return *v, true +} + +// OldHostID returns the old "host_id" field's value of the VirtualMachineRecycleRecord entity. +// If the VirtualMachineRecycleRecord object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *VirtualMachineRecycleRecordMutation) OldHostID(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldHostID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldHostID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldHostID: %w", err) + } + return oldValue.HostID, nil +} + +// ResetHostID resets all changes to the "host_id" field. +func (m *VirtualMachineRecycleRecordMutation) ResetHostID() { + m.host_id = nil +} + +// SetUserID sets the "user_id" field. +func (m *VirtualMachineRecycleRecordMutation) SetUserID(u uuid.UUID) { + m.user_id = &u +} + +// UserID returns the value of the "user_id" field in the mutation. +func (m *VirtualMachineRecycleRecordMutation) UserID() (r uuid.UUID, exists bool) { + v := m.user_id + if v == nil { + return + } + return *v, true +} + +// OldUserID returns the old "user_id" field's value of the VirtualMachineRecycleRecord entity. +// If the VirtualMachineRecycleRecord object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *VirtualMachineRecycleRecordMutation) OldUserID(ctx context.Context) (v *uuid.UUID, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUserID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUserID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUserID: %w", err) + } + return oldValue.UserID, nil +} + +// ClearUserID clears the value of the "user_id" field. +func (m *VirtualMachineRecycleRecordMutation) ClearUserID() { + m.user_id = nil + m.clearedFields[virtualmachinerecyclerecord.FieldUserID] = struct{}{} +} + +// UserIDCleared returns if the "user_id" field was cleared in this mutation. +func (m *VirtualMachineRecycleRecordMutation) UserIDCleared() bool { + _, ok := m.clearedFields[virtualmachinerecyclerecord.FieldUserID] + return ok +} + +// ResetUserID resets all changes to the "user_id" field. +func (m *VirtualMachineRecycleRecordMutation) ResetUserID() { + m.user_id = nil + delete(m.clearedFields, virtualmachinerecyclerecord.FieldUserID) +} + +// SetTaskIds sets the "task_ids" field. +func (m *VirtualMachineRecycleRecordMutation) SetTaskIds(u []uuid.UUID) { + m.task_ids = &u + m.appendtask_ids = nil +} + +// TaskIds returns the value of the "task_ids" field in the mutation. +func (m *VirtualMachineRecycleRecordMutation) TaskIds() (r []uuid.UUID, exists bool) { + v := m.task_ids + if v == nil { + return + } + return *v, true +} + +// OldTaskIds returns the old "task_ids" field's value of the VirtualMachineRecycleRecord entity. +// If the VirtualMachineRecycleRecord object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *VirtualMachineRecycleRecordMutation) OldTaskIds(ctx context.Context) (v []uuid.UUID, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldTaskIds is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldTaskIds requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldTaskIds: %w", err) + } + return oldValue.TaskIds, nil +} + +// AppendTaskIds adds u to the "task_ids" field. +func (m *VirtualMachineRecycleRecordMutation) AppendTaskIds(u []uuid.UUID) { + m.appendtask_ids = append(m.appendtask_ids, u...) +} + +// AppendedTaskIds returns the list of values that were appended to the "task_ids" field in this mutation. +func (m *VirtualMachineRecycleRecordMutation) AppendedTaskIds() ([]uuid.UUID, bool) { + if len(m.appendtask_ids) == 0 { + return nil, false + } + return m.appendtask_ids, true +} + +// ResetTaskIds resets all changes to the "task_ids" field. +func (m *VirtualMachineRecycleRecordMutation) ResetTaskIds() { + m.task_ids = nil + m.appendtask_ids = nil +} + +// SetMethod sets the "method" field. +func (m *VirtualMachineRecycleRecordMutation) SetMethod(crm consts.VMRecycleMethod) { + m.method = &crm +} + +// Method returns the value of the "method" field in the mutation. +func (m *VirtualMachineRecycleRecordMutation) Method() (r consts.VMRecycleMethod, exists bool) { + v := m.method + if v == nil { + return + } + return *v, true +} + +// OldMethod returns the old "method" field's value of the VirtualMachineRecycleRecord entity. +// If the VirtualMachineRecycleRecord object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *VirtualMachineRecycleRecordMutation) OldMethod(ctx context.Context) (v consts.VMRecycleMethod, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldMethod is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldMethod requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldMethod: %w", err) + } + return oldValue.Method, nil +} + +// ResetMethod resets all changes to the "method" field. +func (m *VirtualMachineRecycleRecordMutation) ResetMethod() { + m.method = nil +} + +// SetRemoteDeleted sets the "remote_deleted" field. +func (m *VirtualMachineRecycleRecordMutation) SetRemoteDeleted(b bool) { + m.remote_deleted = &b +} + +// RemoteDeleted returns the value of the "remote_deleted" field in the mutation. +func (m *VirtualMachineRecycleRecordMutation) RemoteDeleted() (r bool, exists bool) { + v := m.remote_deleted + if v == nil { + return + } + return *v, true +} + +// OldRemoteDeleted returns the old "remote_deleted" field's value of the VirtualMachineRecycleRecord entity. +// If the VirtualMachineRecycleRecord object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *VirtualMachineRecycleRecordMutation) OldRemoteDeleted(ctx context.Context) (v bool, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldRemoteDeleted is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldRemoteDeleted requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldRemoteDeleted: %w", err) + } + return oldValue.RemoteDeleted, nil +} + +// ResetRemoteDeleted resets all changes to the "remote_deleted" field. +func (m *VirtualMachineRecycleRecordMutation) ResetRemoteDeleted() { + m.remote_deleted = nil +} + +// SetRecycledAt sets the "recycled_at" field. +func (m *VirtualMachineRecycleRecordMutation) SetRecycledAt(t time.Time) { + m.recycled_at = &t +} + +// RecycledAt returns the value of the "recycled_at" field in the mutation. +func (m *VirtualMachineRecycleRecordMutation) RecycledAt() (r time.Time, exists bool) { + v := m.recycled_at + if v == nil { + return + } + return *v, true +} + +// OldRecycledAt returns the old "recycled_at" field's value of the VirtualMachineRecycleRecord entity. +// If the VirtualMachineRecycleRecord object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *VirtualMachineRecycleRecordMutation) OldRecycledAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldRecycledAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldRecycledAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldRecycledAt: %w", err) + } + return oldValue.RecycledAt, nil +} + +// ResetRecycledAt resets all changes to the "recycled_at" field. +func (m *VirtualMachineRecycleRecordMutation) ResetRecycledAt() { + m.recycled_at = nil +} + +// SetCreatedAt sets the "created_at" field. +func (m *VirtualMachineRecycleRecordMutation) SetCreatedAt(t time.Time) { + m.created_at = &t +} + +// CreatedAt returns the value of the "created_at" field in the mutation. +func (m *VirtualMachineRecycleRecordMutation) CreatedAt() (r time.Time, exists bool) { + v := m.created_at + if v == nil { + return + } + return *v, true +} + +// OldCreatedAt returns the old "created_at" field's value of the VirtualMachineRecycleRecord entity. +// If the VirtualMachineRecycleRecord object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *VirtualMachineRecycleRecordMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldCreatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldCreatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err) + } + return oldValue.CreatedAt, nil +} + +// ResetCreatedAt resets all changes to the "created_at" field. +func (m *VirtualMachineRecycleRecordMutation) ResetCreatedAt() { + m.created_at = nil +} + +// Where appends a list predicates to the VirtualMachineRecycleRecordMutation builder. +func (m *VirtualMachineRecycleRecordMutation) Where(ps ...predicate.VirtualMachineRecycleRecord) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the VirtualMachineRecycleRecordMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *VirtualMachineRecycleRecordMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.VirtualMachineRecycleRecord, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *VirtualMachineRecycleRecordMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *VirtualMachineRecycleRecordMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (VirtualMachineRecycleRecord). +func (m *VirtualMachineRecycleRecordMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *VirtualMachineRecycleRecordMutation) Fields() []string { + fields := make([]string, 0, 9) + if m.virtualmachine_id != nil { + fields = append(fields, virtualmachinerecyclerecord.FieldVirtualmachineID) + } + if m.environment_id != nil { + fields = append(fields, virtualmachinerecyclerecord.FieldEnvironmentID) + } + if m.host_id != nil { + fields = append(fields, virtualmachinerecyclerecord.FieldHostID) + } + if m.user_id != nil { + fields = append(fields, virtualmachinerecyclerecord.FieldUserID) + } + if m.task_ids != nil { + fields = append(fields, virtualmachinerecyclerecord.FieldTaskIds) + } + if m.method != nil { + fields = append(fields, virtualmachinerecyclerecord.FieldMethod) + } + if m.remote_deleted != nil { + fields = append(fields, virtualmachinerecyclerecord.FieldRemoteDeleted) + } + if m.recycled_at != nil { + fields = append(fields, virtualmachinerecyclerecord.FieldRecycledAt) + } + if m.created_at != nil { + fields = append(fields, virtualmachinerecyclerecord.FieldCreatedAt) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *VirtualMachineRecycleRecordMutation) Field(name string) (ent.Value, bool) { + switch name { + case virtualmachinerecyclerecord.FieldVirtualmachineID: + return m.VirtualmachineID() + case virtualmachinerecyclerecord.FieldEnvironmentID: + return m.EnvironmentID() + case virtualmachinerecyclerecord.FieldHostID: + return m.HostID() + case virtualmachinerecyclerecord.FieldUserID: + return m.UserID() + case virtualmachinerecyclerecord.FieldTaskIds: + return m.TaskIds() + case virtualmachinerecyclerecord.FieldMethod: + return m.Method() + case virtualmachinerecyclerecord.FieldRemoteDeleted: + return m.RemoteDeleted() + case virtualmachinerecyclerecord.FieldRecycledAt: + return m.RecycledAt() + case virtualmachinerecyclerecord.FieldCreatedAt: + return m.CreatedAt() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *VirtualMachineRecycleRecordMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case virtualmachinerecyclerecord.FieldVirtualmachineID: + return m.OldVirtualmachineID(ctx) + case virtualmachinerecyclerecord.FieldEnvironmentID: + return m.OldEnvironmentID(ctx) + case virtualmachinerecyclerecord.FieldHostID: + return m.OldHostID(ctx) + case virtualmachinerecyclerecord.FieldUserID: + return m.OldUserID(ctx) + case virtualmachinerecyclerecord.FieldTaskIds: + return m.OldTaskIds(ctx) + case virtualmachinerecyclerecord.FieldMethod: + return m.OldMethod(ctx) + case virtualmachinerecyclerecord.FieldRemoteDeleted: + return m.OldRemoteDeleted(ctx) + case virtualmachinerecyclerecord.FieldRecycledAt: + return m.OldRecycledAt(ctx) + case virtualmachinerecyclerecord.FieldCreatedAt: + return m.OldCreatedAt(ctx) + } + return nil, fmt.Errorf("unknown VirtualMachineRecycleRecord field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *VirtualMachineRecycleRecordMutation) SetField(name string, value ent.Value) error { + switch name { + case virtualmachinerecyclerecord.FieldVirtualmachineID: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetVirtualmachineID(v) + return nil + case virtualmachinerecyclerecord.FieldEnvironmentID: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetEnvironmentID(v) + return nil + case virtualmachinerecyclerecord.FieldHostID: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetHostID(v) + return nil + case virtualmachinerecyclerecord.FieldUserID: + v, ok := value.(uuid.UUID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUserID(v) + return nil + case virtualmachinerecyclerecord.FieldTaskIds: + v, ok := value.([]uuid.UUID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetTaskIds(v) + return nil + case virtualmachinerecyclerecord.FieldMethod: + v, ok := value.(consts.VMRecycleMethod) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetMethod(v) + return nil + case virtualmachinerecyclerecord.FieldRemoteDeleted: + v, ok := value.(bool) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRemoteDeleted(v) + return nil + case virtualmachinerecyclerecord.FieldRecycledAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRecycledAt(v) + return nil + case virtualmachinerecyclerecord.FieldCreatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetCreatedAt(v) + return nil + } + return fmt.Errorf("unknown VirtualMachineRecycleRecord field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *VirtualMachineRecycleRecordMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *VirtualMachineRecycleRecordMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *VirtualMachineRecycleRecordMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown VirtualMachineRecycleRecord numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *VirtualMachineRecycleRecordMutation) ClearedFields() []string { + var fields []string + if m.FieldCleared(virtualmachinerecyclerecord.FieldUserID) { + fields = append(fields, virtualmachinerecyclerecord.FieldUserID) + } + return fields +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *VirtualMachineRecycleRecordMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *VirtualMachineRecycleRecordMutation) ClearField(name string) error { + switch name { + case virtualmachinerecyclerecord.FieldUserID: + m.ClearUserID() + return nil + } + return fmt.Errorf("unknown VirtualMachineRecycleRecord nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *VirtualMachineRecycleRecordMutation) ResetField(name string) error { + switch name { + case virtualmachinerecyclerecord.FieldVirtualmachineID: + m.ResetVirtualmachineID() + return nil + case virtualmachinerecyclerecord.FieldEnvironmentID: + m.ResetEnvironmentID() + return nil + case virtualmachinerecyclerecord.FieldHostID: + m.ResetHostID() + return nil + case virtualmachinerecyclerecord.FieldUserID: + m.ResetUserID() + return nil + case virtualmachinerecyclerecord.FieldTaskIds: + m.ResetTaskIds() + return nil + case virtualmachinerecyclerecord.FieldMethod: + m.ResetMethod() + return nil + case virtualmachinerecyclerecord.FieldRemoteDeleted: + m.ResetRemoteDeleted() + return nil + case virtualmachinerecyclerecord.FieldRecycledAt: + m.ResetRecycledAt() + return nil + case virtualmachinerecyclerecord.FieldCreatedAt: + m.ResetCreatedAt() + return nil + } + return fmt.Errorf("unknown VirtualMachineRecycleRecord field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *VirtualMachineRecycleRecordMutation) AddedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *VirtualMachineRecycleRecordMutation) AddedIDs(name string) []ent.Value { + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *VirtualMachineRecycleRecordMutation) RemovedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *VirtualMachineRecycleRecordMutation) RemovedIDs(name string) []ent.Value { + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *VirtualMachineRecycleRecordMutation) ClearedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *VirtualMachineRecycleRecordMutation) EdgeCleared(name string) bool { + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *VirtualMachineRecycleRecordMutation) ClearEdge(name string) error { + return fmt.Errorf("unknown VirtualMachineRecycleRecord unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *VirtualMachineRecycleRecordMutation) ResetEdge(name string) error { + return fmt.Errorf("unknown VirtualMachineRecycleRecord edge %s", name) +} diff --git a/backend/db/page.go b/backend/db/page.go index a6998d712..8e5aeb74d 100644 --- a/backend/db/page.go +++ b/backend/db/page.go @@ -766,3 +766,17 @@ func (_m *VirtualMachineQuery) Page(ctx context.Context, page, size int) ([]*Vir has := (page * size) < cnt return rs, &PageInfo{HasNextPage: has, TotalCount: int64(cnt)}, nil } + +func (_m *VirtualMachineRecycleRecordQuery) Page(ctx context.Context, page, size int) ([]*VirtualMachineRecycleRecord, *PageInfo, error) { + cnt, err := _m.Count(ctx) + if err != nil { + return nil, nil, err + } + offset := size * (page - 1) + rs, err := _m.Offset(offset).Limit(size).All(ctx) + if err != nil { + return nil, nil, err + } + has := (page * size) < cnt + return rs, &PageInfo{HasNextPage: has, TotalCount: int64(cnt)}, nil +} diff --git a/backend/db/predicate/predicate.go b/backend/db/predicate/predicate.go index 7fbaf7a3a..3a38bdcc5 100644 --- a/backend/db/predicate/predicate.go +++ b/backend/db/predicate/predicate.go @@ -167,3 +167,6 @@ type UserIdentity func(*sql.Selector) // VirtualMachine is the predicate function for virtualmachine builders. type VirtualMachine func(*sql.Selector) + +// VirtualMachineRecycleRecord is the predicate function for virtualmachinerecyclerecord builders. +type VirtualMachineRecycleRecord func(*sql.Selector) diff --git a/backend/db/runtime/runtime.go b/backend/db/runtime/runtime.go index f84f97bc2..12e4d95fa 100644 --- a/backend/db/runtime/runtime.go +++ b/backend/db/runtime/runtime.go @@ -60,6 +60,7 @@ import ( "github.com/chaitin/MonkeyCode/backend/db/user" "github.com/chaitin/MonkeyCode/backend/db/useridentity" "github.com/chaitin/MonkeyCode/backend/db/virtualmachine" + "github.com/chaitin/MonkeyCode/backend/db/virtualmachinerecyclerecord" "github.com/chaitin/MonkeyCode/backend/ent/schema" "github.com/google/uuid" ) @@ -1346,6 +1347,16 @@ func init() { virtualmachineDescUpdatedAt := virtualmachineFields[24].Descriptor() // virtualmachine.DefaultUpdatedAt holds the default value on creation for the updated_at field. virtualmachine.DefaultUpdatedAt = virtualmachineDescUpdatedAt.Default.(func() time.Time) + virtualmachinerecyclerecordFields := schema.VirtualMachineRecycleRecord{}.Fields() + _ = virtualmachinerecyclerecordFields + // virtualmachinerecyclerecordDescRemoteDeleted is the schema descriptor for remote_deleted field. + virtualmachinerecyclerecordDescRemoteDeleted := virtualmachinerecyclerecordFields[7].Descriptor() + // virtualmachinerecyclerecord.DefaultRemoteDeleted holds the default value on creation for the remote_deleted field. + virtualmachinerecyclerecord.DefaultRemoteDeleted = virtualmachinerecyclerecordDescRemoteDeleted.Default.(bool) + // virtualmachinerecyclerecordDescCreatedAt is the schema descriptor for created_at field. + virtualmachinerecyclerecordDescCreatedAt := virtualmachinerecyclerecordFields[9].Descriptor() + // virtualmachinerecyclerecord.DefaultCreatedAt holds the default value on creation for the created_at field. + virtualmachinerecyclerecord.DefaultCreatedAt = virtualmachinerecyclerecordDescCreatedAt.Default.(func() time.Time) } const ( diff --git a/backend/db/tx.go b/backend/db/tx.go index a3704aa2e..f54b52de9 100644 --- a/backend/db/tx.go +++ b/backend/db/tx.go @@ -122,6 +122,8 @@ type Tx struct { UserIdentity *UserIdentityClient // VirtualMachine is the client for interacting with the VirtualMachine builders. VirtualMachine *VirtualMachineClient + // VirtualMachineRecycleRecord is the client for interacting with the VirtualMachineRecycleRecord builders. + VirtualMachineRecycleRecord *VirtualMachineRecycleRecordClient // lazily loaded. client *Client @@ -307,6 +309,7 @@ func (tx *Tx) init() { tx.User = NewUserClient(tx.config) tx.UserIdentity = NewUserIdentityClient(tx.config) tx.VirtualMachine = NewVirtualMachineClient(tx.config) + tx.VirtualMachineRecycleRecord = NewVirtualMachineRecycleRecordClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. diff --git a/backend/db/virtualmachinerecyclerecord.go b/backend/db/virtualmachinerecyclerecord.go new file mode 100644 index 000000000..82c14b074 --- /dev/null +++ b/backend/db/virtualmachinerecyclerecord.go @@ -0,0 +1,208 @@ +// Code generated by ent, DO NOT EDIT. + +package db + +import ( + "encoding/json" + "fmt" + "strings" + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "github.com/chaitin/MonkeyCode/backend/consts" + "github.com/chaitin/MonkeyCode/backend/db/virtualmachinerecyclerecord" + "github.com/google/uuid" +) + +// VirtualMachineRecycleRecord is the model entity for the VirtualMachineRecycleRecord schema. +type VirtualMachineRecycleRecord struct { + config `json:"-"` + // ID of the ent. + ID uuid.UUID `json:"id,omitempty"` + // VirtualmachineID holds the value of the "virtualmachine_id" field. + VirtualmachineID string `json:"virtualmachine_id,omitempty"` + // EnvironmentID holds the value of the "environment_id" field. + EnvironmentID string `json:"environment_id,omitempty"` + // HostID holds the value of the "host_id" field. + HostID string `json:"host_id,omitempty"` + // UserID holds the value of the "user_id" field. + UserID *uuid.UUID `json:"user_id,omitempty"` + // TaskIds holds the value of the "task_ids" field. + TaskIds []uuid.UUID `json:"task_ids,omitempty"` + // Method holds the value of the "method" field. + Method consts.VMRecycleMethod `json:"method,omitempty"` + // RemoteDeleted holds the value of the "remote_deleted" field. + RemoteDeleted bool `json:"remote_deleted,omitempty"` + // RecycledAt holds the value of the "recycled_at" field. + RecycledAt time.Time `json:"recycled_at,omitempty"` + // CreatedAt holds the value of the "created_at" field. + CreatedAt time.Time `json:"created_at,omitempty"` + selectValues sql.SelectValues +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*VirtualMachineRecycleRecord) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case virtualmachinerecyclerecord.FieldUserID: + values[i] = &sql.NullScanner{S: new(uuid.UUID)} + case virtualmachinerecyclerecord.FieldTaskIds: + values[i] = new([]byte) + case virtualmachinerecyclerecord.FieldRemoteDeleted: + values[i] = new(sql.NullBool) + case virtualmachinerecyclerecord.FieldVirtualmachineID, virtualmachinerecyclerecord.FieldEnvironmentID, virtualmachinerecyclerecord.FieldHostID, virtualmachinerecyclerecord.FieldMethod: + values[i] = new(sql.NullString) + case virtualmachinerecyclerecord.FieldRecycledAt, virtualmachinerecyclerecord.FieldCreatedAt: + values[i] = new(sql.NullTime) + case virtualmachinerecyclerecord.FieldID: + values[i] = new(uuid.UUID) + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the VirtualMachineRecycleRecord fields. +func (_m *VirtualMachineRecycleRecord) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case virtualmachinerecyclerecord.FieldID: + if value, ok := values[i].(*uuid.UUID); !ok { + return fmt.Errorf("unexpected type %T for field id", values[i]) + } else if value != nil { + _m.ID = *value + } + case virtualmachinerecyclerecord.FieldVirtualmachineID: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field virtualmachine_id", values[i]) + } else if value.Valid { + _m.VirtualmachineID = value.String + } + case virtualmachinerecyclerecord.FieldEnvironmentID: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field environment_id", values[i]) + } else if value.Valid { + _m.EnvironmentID = value.String + } + case virtualmachinerecyclerecord.FieldHostID: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field host_id", values[i]) + } else if value.Valid { + _m.HostID = value.String + } + case virtualmachinerecyclerecord.FieldUserID: + if value, ok := values[i].(*sql.NullScanner); !ok { + return fmt.Errorf("unexpected type %T for field user_id", values[i]) + } else if value.Valid { + _m.UserID = new(uuid.UUID) + *_m.UserID = *value.S.(*uuid.UUID) + } + case virtualmachinerecyclerecord.FieldTaskIds: + if value, ok := values[i].(*[]byte); !ok { + return fmt.Errorf("unexpected type %T for field task_ids", values[i]) + } else if value != nil && len(*value) > 0 { + if err := json.Unmarshal(*value, &_m.TaskIds); err != nil { + return fmt.Errorf("unmarshal field task_ids: %w", err) + } + } + case virtualmachinerecyclerecord.FieldMethod: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field method", values[i]) + } else if value.Valid { + _m.Method = consts.VMRecycleMethod(value.String) + } + case virtualmachinerecyclerecord.FieldRemoteDeleted: + if value, ok := values[i].(*sql.NullBool); !ok { + return fmt.Errorf("unexpected type %T for field remote_deleted", values[i]) + } else if value.Valid { + _m.RemoteDeleted = value.Bool + } + case virtualmachinerecyclerecord.FieldRecycledAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field recycled_at", values[i]) + } else if value.Valid { + _m.RecycledAt = value.Time + } + case virtualmachinerecyclerecord.FieldCreatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field created_at", values[i]) + } else if value.Valid { + _m.CreatedAt = value.Time + } + default: + _m.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// Value returns the ent.Value that was dynamically selected and assigned to the VirtualMachineRecycleRecord. +// This includes values selected through modifiers, order, etc. +func (_m *VirtualMachineRecycleRecord) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + +// Update returns a builder for updating this VirtualMachineRecycleRecord. +// Note that you need to call VirtualMachineRecycleRecord.Unwrap() before calling this method if this VirtualMachineRecycleRecord +// was returned from a transaction, and the transaction was committed or rolled back. +func (_m *VirtualMachineRecycleRecord) Update() *VirtualMachineRecycleRecordUpdateOne { + return NewVirtualMachineRecycleRecordClient(_m.config).UpdateOne(_m) +} + +// Unwrap unwraps the VirtualMachineRecycleRecord entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (_m *VirtualMachineRecycleRecord) Unwrap() *VirtualMachineRecycleRecord { + _tx, ok := _m.config.driver.(*txDriver) + if !ok { + panic("db: VirtualMachineRecycleRecord is not a transactional entity") + } + _m.config.driver = _tx.drv + return _m +} + +// String implements the fmt.Stringer. +func (_m *VirtualMachineRecycleRecord) String() string { + var builder strings.Builder + builder.WriteString("VirtualMachineRecycleRecord(") + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) + builder.WriteString("virtualmachine_id=") + builder.WriteString(_m.VirtualmachineID) + builder.WriteString(", ") + builder.WriteString("environment_id=") + builder.WriteString(_m.EnvironmentID) + builder.WriteString(", ") + builder.WriteString("host_id=") + builder.WriteString(_m.HostID) + builder.WriteString(", ") + if v := _m.UserID; v != nil { + builder.WriteString("user_id=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } + builder.WriteString(", ") + builder.WriteString("task_ids=") + builder.WriteString(fmt.Sprintf("%v", _m.TaskIds)) + builder.WriteString(", ") + builder.WriteString("method=") + builder.WriteString(fmt.Sprintf("%v", _m.Method)) + builder.WriteString(", ") + builder.WriteString("remote_deleted=") + builder.WriteString(fmt.Sprintf("%v", _m.RemoteDeleted)) + builder.WriteString(", ") + builder.WriteString("recycled_at=") + builder.WriteString(_m.RecycledAt.Format(time.ANSIC)) + builder.WriteString(", ") + builder.WriteString("created_at=") + builder.WriteString(_m.CreatedAt.Format(time.ANSIC)) + builder.WriteByte(')') + return builder.String() +} + +// VirtualMachineRecycleRecords is a parsable slice of VirtualMachineRecycleRecord. +type VirtualMachineRecycleRecords []*VirtualMachineRecycleRecord diff --git a/backend/db/virtualmachinerecyclerecord/virtualmachinerecyclerecord.go b/backend/db/virtualmachinerecyclerecord/virtualmachinerecyclerecord.go new file mode 100644 index 000000000..80f5ce0d0 --- /dev/null +++ b/backend/db/virtualmachinerecyclerecord/virtualmachinerecyclerecord.go @@ -0,0 +1,115 @@ +// Code generated by ent, DO NOT EDIT. + +package virtualmachinerecyclerecord + +import ( + "time" + + "entgo.io/ent/dialect/sql" +) + +const ( + // Label holds the string label denoting the virtualmachinerecyclerecord type in the database. + Label = "virtual_machine_recycle_record" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldVirtualmachineID holds the string denoting the virtualmachine_id field in the database. + FieldVirtualmachineID = "virtualmachine_id" + // FieldEnvironmentID holds the string denoting the environment_id field in the database. + FieldEnvironmentID = "environment_id" + // FieldHostID holds the string denoting the host_id field in the database. + FieldHostID = "host_id" + // FieldUserID holds the string denoting the user_id field in the database. + FieldUserID = "user_id" + // FieldTaskIds holds the string denoting the task_ids field in the database. + FieldTaskIds = "task_ids" + // FieldMethod holds the string denoting the method field in the database. + FieldMethod = "method" + // FieldRemoteDeleted holds the string denoting the remote_deleted field in the database. + FieldRemoteDeleted = "remote_deleted" + // FieldRecycledAt holds the string denoting the recycled_at field in the database. + FieldRecycledAt = "recycled_at" + // FieldCreatedAt holds the string denoting the created_at field in the database. + FieldCreatedAt = "created_at" + // Table holds the table name of the virtualmachinerecyclerecord in the database. + Table = "virtualmachine_recycle_records" +) + +// Columns holds all SQL columns for virtualmachinerecyclerecord fields. +var Columns = []string{ + FieldID, + FieldVirtualmachineID, + FieldEnvironmentID, + FieldHostID, + FieldUserID, + FieldTaskIds, + FieldMethod, + FieldRemoteDeleted, + FieldRecycledAt, + FieldCreatedAt, +} + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + return false +} + +var ( + // DefaultRemoteDeleted holds the default value on creation for the "remote_deleted" field. + DefaultRemoteDeleted bool + // DefaultCreatedAt holds the default value on creation for the "created_at" field. + DefaultCreatedAt func() time.Time +) + +// OrderOption defines the ordering options for the VirtualMachineRecycleRecord queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByVirtualmachineID orders the results by the virtualmachine_id field. +func ByVirtualmachineID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldVirtualmachineID, opts...).ToFunc() +} + +// ByEnvironmentID orders the results by the environment_id field. +func ByEnvironmentID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldEnvironmentID, opts...).ToFunc() +} + +// ByHostID orders the results by the host_id field. +func ByHostID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldHostID, opts...).ToFunc() +} + +// ByUserID orders the results by the user_id field. +func ByUserID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUserID, opts...).ToFunc() +} + +// ByMethod orders the results by the method field. +func ByMethod(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldMethod, opts...).ToFunc() +} + +// ByRemoteDeleted orders the results by the remote_deleted field. +func ByRemoteDeleted(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldRemoteDeleted, opts...).ToFunc() +} + +// ByRecycledAt orders the results by the recycled_at field. +func ByRecycledAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldRecycledAt, opts...).ToFunc() +} + +// ByCreatedAt orders the results by the created_at field. +func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldCreatedAt, opts...).ToFunc() +} diff --git a/backend/db/virtualmachinerecyclerecord/where.go b/backend/db/virtualmachinerecyclerecord/where.go new file mode 100644 index 000000000..db3d4eafa --- /dev/null +++ b/backend/db/virtualmachinerecyclerecord/where.go @@ -0,0 +1,532 @@ +// Code generated by ent, DO NOT EDIT. + +package virtualmachinerecyclerecord + +import ( + "time" + + "entgo.io/ent/dialect/sql" + "github.com/chaitin/MonkeyCode/backend/consts" + "github.com/chaitin/MonkeyCode/backend/db/predicate" + "github.com/google/uuid" +) + +// ID filters vertices based on their ID field. +func ID(id uuid.UUID) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id uuid.UUID) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id uuid.UUID) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...uuid.UUID) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...uuid.UUID) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id uuid.UUID) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id uuid.UUID) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id uuid.UUID) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id uuid.UUID) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldLTE(FieldID, id)) +} + +// VirtualmachineID applies equality check predicate on the "virtualmachine_id" field. It's identical to VirtualmachineIDEQ. +func VirtualmachineID(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldEQ(FieldVirtualmachineID, v)) +} + +// EnvironmentID applies equality check predicate on the "environment_id" field. It's identical to EnvironmentIDEQ. +func EnvironmentID(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldEQ(FieldEnvironmentID, v)) +} + +// HostID applies equality check predicate on the "host_id" field. It's identical to HostIDEQ. +func HostID(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldEQ(FieldHostID, v)) +} + +// UserID applies equality check predicate on the "user_id" field. It's identical to UserIDEQ. +func UserID(v uuid.UUID) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldEQ(FieldUserID, v)) +} + +// Method applies equality check predicate on the "method" field. It's identical to MethodEQ. +func Method(v consts.VMRecycleMethod) predicate.VirtualMachineRecycleRecord { + vc := string(v) + return predicate.VirtualMachineRecycleRecord(sql.FieldEQ(FieldMethod, vc)) +} + +// RemoteDeleted applies equality check predicate on the "remote_deleted" field. It's identical to RemoteDeletedEQ. +func RemoteDeleted(v bool) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldEQ(FieldRemoteDeleted, v)) +} + +// RecycledAt applies equality check predicate on the "recycled_at" field. It's identical to RecycledAtEQ. +func RecycledAt(v time.Time) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldEQ(FieldRecycledAt, v)) +} + +// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ. +func CreatedAt(v time.Time) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldEQ(FieldCreatedAt, v)) +} + +// VirtualmachineIDEQ applies the EQ predicate on the "virtualmachine_id" field. +func VirtualmachineIDEQ(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldEQ(FieldVirtualmachineID, v)) +} + +// VirtualmachineIDNEQ applies the NEQ predicate on the "virtualmachine_id" field. +func VirtualmachineIDNEQ(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldNEQ(FieldVirtualmachineID, v)) +} + +// VirtualmachineIDIn applies the In predicate on the "virtualmachine_id" field. +func VirtualmachineIDIn(vs ...string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldIn(FieldVirtualmachineID, vs...)) +} + +// VirtualmachineIDNotIn applies the NotIn predicate on the "virtualmachine_id" field. +func VirtualmachineIDNotIn(vs ...string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldNotIn(FieldVirtualmachineID, vs...)) +} + +// VirtualmachineIDGT applies the GT predicate on the "virtualmachine_id" field. +func VirtualmachineIDGT(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldGT(FieldVirtualmachineID, v)) +} + +// VirtualmachineIDGTE applies the GTE predicate on the "virtualmachine_id" field. +func VirtualmachineIDGTE(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldGTE(FieldVirtualmachineID, v)) +} + +// VirtualmachineIDLT applies the LT predicate on the "virtualmachine_id" field. +func VirtualmachineIDLT(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldLT(FieldVirtualmachineID, v)) +} + +// VirtualmachineIDLTE applies the LTE predicate on the "virtualmachine_id" field. +func VirtualmachineIDLTE(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldLTE(FieldVirtualmachineID, v)) +} + +// VirtualmachineIDContains applies the Contains predicate on the "virtualmachine_id" field. +func VirtualmachineIDContains(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldContains(FieldVirtualmachineID, v)) +} + +// VirtualmachineIDHasPrefix applies the HasPrefix predicate on the "virtualmachine_id" field. +func VirtualmachineIDHasPrefix(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldHasPrefix(FieldVirtualmachineID, v)) +} + +// VirtualmachineIDHasSuffix applies the HasSuffix predicate on the "virtualmachine_id" field. +func VirtualmachineIDHasSuffix(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldHasSuffix(FieldVirtualmachineID, v)) +} + +// VirtualmachineIDEqualFold applies the EqualFold predicate on the "virtualmachine_id" field. +func VirtualmachineIDEqualFold(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldEqualFold(FieldVirtualmachineID, v)) +} + +// VirtualmachineIDContainsFold applies the ContainsFold predicate on the "virtualmachine_id" field. +func VirtualmachineIDContainsFold(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldContainsFold(FieldVirtualmachineID, v)) +} + +// EnvironmentIDEQ applies the EQ predicate on the "environment_id" field. +func EnvironmentIDEQ(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldEQ(FieldEnvironmentID, v)) +} + +// EnvironmentIDNEQ applies the NEQ predicate on the "environment_id" field. +func EnvironmentIDNEQ(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldNEQ(FieldEnvironmentID, v)) +} + +// EnvironmentIDIn applies the In predicate on the "environment_id" field. +func EnvironmentIDIn(vs ...string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldIn(FieldEnvironmentID, vs...)) +} + +// EnvironmentIDNotIn applies the NotIn predicate on the "environment_id" field. +func EnvironmentIDNotIn(vs ...string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldNotIn(FieldEnvironmentID, vs...)) +} + +// EnvironmentIDGT applies the GT predicate on the "environment_id" field. +func EnvironmentIDGT(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldGT(FieldEnvironmentID, v)) +} + +// EnvironmentIDGTE applies the GTE predicate on the "environment_id" field. +func EnvironmentIDGTE(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldGTE(FieldEnvironmentID, v)) +} + +// EnvironmentIDLT applies the LT predicate on the "environment_id" field. +func EnvironmentIDLT(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldLT(FieldEnvironmentID, v)) +} + +// EnvironmentIDLTE applies the LTE predicate on the "environment_id" field. +func EnvironmentIDLTE(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldLTE(FieldEnvironmentID, v)) +} + +// EnvironmentIDContains applies the Contains predicate on the "environment_id" field. +func EnvironmentIDContains(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldContains(FieldEnvironmentID, v)) +} + +// EnvironmentIDHasPrefix applies the HasPrefix predicate on the "environment_id" field. +func EnvironmentIDHasPrefix(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldHasPrefix(FieldEnvironmentID, v)) +} + +// EnvironmentIDHasSuffix applies the HasSuffix predicate on the "environment_id" field. +func EnvironmentIDHasSuffix(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldHasSuffix(FieldEnvironmentID, v)) +} + +// EnvironmentIDEqualFold applies the EqualFold predicate on the "environment_id" field. +func EnvironmentIDEqualFold(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldEqualFold(FieldEnvironmentID, v)) +} + +// EnvironmentIDContainsFold applies the ContainsFold predicate on the "environment_id" field. +func EnvironmentIDContainsFold(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldContainsFold(FieldEnvironmentID, v)) +} + +// HostIDEQ applies the EQ predicate on the "host_id" field. +func HostIDEQ(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldEQ(FieldHostID, v)) +} + +// HostIDNEQ applies the NEQ predicate on the "host_id" field. +func HostIDNEQ(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldNEQ(FieldHostID, v)) +} + +// HostIDIn applies the In predicate on the "host_id" field. +func HostIDIn(vs ...string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldIn(FieldHostID, vs...)) +} + +// HostIDNotIn applies the NotIn predicate on the "host_id" field. +func HostIDNotIn(vs ...string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldNotIn(FieldHostID, vs...)) +} + +// HostIDGT applies the GT predicate on the "host_id" field. +func HostIDGT(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldGT(FieldHostID, v)) +} + +// HostIDGTE applies the GTE predicate on the "host_id" field. +func HostIDGTE(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldGTE(FieldHostID, v)) +} + +// HostIDLT applies the LT predicate on the "host_id" field. +func HostIDLT(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldLT(FieldHostID, v)) +} + +// HostIDLTE applies the LTE predicate on the "host_id" field. +func HostIDLTE(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldLTE(FieldHostID, v)) +} + +// HostIDContains applies the Contains predicate on the "host_id" field. +func HostIDContains(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldContains(FieldHostID, v)) +} + +// HostIDHasPrefix applies the HasPrefix predicate on the "host_id" field. +func HostIDHasPrefix(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldHasPrefix(FieldHostID, v)) +} + +// HostIDHasSuffix applies the HasSuffix predicate on the "host_id" field. +func HostIDHasSuffix(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldHasSuffix(FieldHostID, v)) +} + +// HostIDEqualFold applies the EqualFold predicate on the "host_id" field. +func HostIDEqualFold(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldEqualFold(FieldHostID, v)) +} + +// HostIDContainsFold applies the ContainsFold predicate on the "host_id" field. +func HostIDContainsFold(v string) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldContainsFold(FieldHostID, v)) +} + +// UserIDEQ applies the EQ predicate on the "user_id" field. +func UserIDEQ(v uuid.UUID) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldEQ(FieldUserID, v)) +} + +// UserIDNEQ applies the NEQ predicate on the "user_id" field. +func UserIDNEQ(v uuid.UUID) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldNEQ(FieldUserID, v)) +} + +// UserIDIn applies the In predicate on the "user_id" field. +func UserIDIn(vs ...uuid.UUID) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldIn(FieldUserID, vs...)) +} + +// UserIDNotIn applies the NotIn predicate on the "user_id" field. +func UserIDNotIn(vs ...uuid.UUID) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldNotIn(FieldUserID, vs...)) +} + +// UserIDGT applies the GT predicate on the "user_id" field. +func UserIDGT(v uuid.UUID) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldGT(FieldUserID, v)) +} + +// UserIDGTE applies the GTE predicate on the "user_id" field. +func UserIDGTE(v uuid.UUID) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldGTE(FieldUserID, v)) +} + +// UserIDLT applies the LT predicate on the "user_id" field. +func UserIDLT(v uuid.UUID) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldLT(FieldUserID, v)) +} + +// UserIDLTE applies the LTE predicate on the "user_id" field. +func UserIDLTE(v uuid.UUID) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldLTE(FieldUserID, v)) +} + +// UserIDIsNil applies the IsNil predicate on the "user_id" field. +func UserIDIsNil() predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldIsNull(FieldUserID)) +} + +// UserIDNotNil applies the NotNil predicate on the "user_id" field. +func UserIDNotNil() predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldNotNull(FieldUserID)) +} + +// MethodEQ applies the EQ predicate on the "method" field. +func MethodEQ(v consts.VMRecycleMethod) predicate.VirtualMachineRecycleRecord { + vc := string(v) + return predicate.VirtualMachineRecycleRecord(sql.FieldEQ(FieldMethod, vc)) +} + +// MethodNEQ applies the NEQ predicate on the "method" field. +func MethodNEQ(v consts.VMRecycleMethod) predicate.VirtualMachineRecycleRecord { + vc := string(v) + return predicate.VirtualMachineRecycleRecord(sql.FieldNEQ(FieldMethod, vc)) +} + +// MethodIn applies the In predicate on the "method" field. +func MethodIn(vs ...consts.VMRecycleMethod) predicate.VirtualMachineRecycleRecord { + v := make([]any, len(vs)) + for i := range v { + v[i] = string(vs[i]) + } + return predicate.VirtualMachineRecycleRecord(sql.FieldIn(FieldMethod, v...)) +} + +// MethodNotIn applies the NotIn predicate on the "method" field. +func MethodNotIn(vs ...consts.VMRecycleMethod) predicate.VirtualMachineRecycleRecord { + v := make([]any, len(vs)) + for i := range v { + v[i] = string(vs[i]) + } + return predicate.VirtualMachineRecycleRecord(sql.FieldNotIn(FieldMethod, v...)) +} + +// MethodGT applies the GT predicate on the "method" field. +func MethodGT(v consts.VMRecycleMethod) predicate.VirtualMachineRecycleRecord { + vc := string(v) + return predicate.VirtualMachineRecycleRecord(sql.FieldGT(FieldMethod, vc)) +} + +// MethodGTE applies the GTE predicate on the "method" field. +func MethodGTE(v consts.VMRecycleMethod) predicate.VirtualMachineRecycleRecord { + vc := string(v) + return predicate.VirtualMachineRecycleRecord(sql.FieldGTE(FieldMethod, vc)) +} + +// MethodLT applies the LT predicate on the "method" field. +func MethodLT(v consts.VMRecycleMethod) predicate.VirtualMachineRecycleRecord { + vc := string(v) + return predicate.VirtualMachineRecycleRecord(sql.FieldLT(FieldMethod, vc)) +} + +// MethodLTE applies the LTE predicate on the "method" field. +func MethodLTE(v consts.VMRecycleMethod) predicate.VirtualMachineRecycleRecord { + vc := string(v) + return predicate.VirtualMachineRecycleRecord(sql.FieldLTE(FieldMethod, vc)) +} + +// MethodContains applies the Contains predicate on the "method" field. +func MethodContains(v consts.VMRecycleMethod) predicate.VirtualMachineRecycleRecord { + vc := string(v) + return predicate.VirtualMachineRecycleRecord(sql.FieldContains(FieldMethod, vc)) +} + +// MethodHasPrefix applies the HasPrefix predicate on the "method" field. +func MethodHasPrefix(v consts.VMRecycleMethod) predicate.VirtualMachineRecycleRecord { + vc := string(v) + return predicate.VirtualMachineRecycleRecord(sql.FieldHasPrefix(FieldMethod, vc)) +} + +// MethodHasSuffix applies the HasSuffix predicate on the "method" field. +func MethodHasSuffix(v consts.VMRecycleMethod) predicate.VirtualMachineRecycleRecord { + vc := string(v) + return predicate.VirtualMachineRecycleRecord(sql.FieldHasSuffix(FieldMethod, vc)) +} + +// MethodEqualFold applies the EqualFold predicate on the "method" field. +func MethodEqualFold(v consts.VMRecycleMethod) predicate.VirtualMachineRecycleRecord { + vc := string(v) + return predicate.VirtualMachineRecycleRecord(sql.FieldEqualFold(FieldMethod, vc)) +} + +// MethodContainsFold applies the ContainsFold predicate on the "method" field. +func MethodContainsFold(v consts.VMRecycleMethod) predicate.VirtualMachineRecycleRecord { + vc := string(v) + return predicate.VirtualMachineRecycleRecord(sql.FieldContainsFold(FieldMethod, vc)) +} + +// RemoteDeletedEQ applies the EQ predicate on the "remote_deleted" field. +func RemoteDeletedEQ(v bool) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldEQ(FieldRemoteDeleted, v)) +} + +// RemoteDeletedNEQ applies the NEQ predicate on the "remote_deleted" field. +func RemoteDeletedNEQ(v bool) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldNEQ(FieldRemoteDeleted, v)) +} + +// RecycledAtEQ applies the EQ predicate on the "recycled_at" field. +func RecycledAtEQ(v time.Time) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldEQ(FieldRecycledAt, v)) +} + +// RecycledAtNEQ applies the NEQ predicate on the "recycled_at" field. +func RecycledAtNEQ(v time.Time) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldNEQ(FieldRecycledAt, v)) +} + +// RecycledAtIn applies the In predicate on the "recycled_at" field. +func RecycledAtIn(vs ...time.Time) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldIn(FieldRecycledAt, vs...)) +} + +// RecycledAtNotIn applies the NotIn predicate on the "recycled_at" field. +func RecycledAtNotIn(vs ...time.Time) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldNotIn(FieldRecycledAt, vs...)) +} + +// RecycledAtGT applies the GT predicate on the "recycled_at" field. +func RecycledAtGT(v time.Time) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldGT(FieldRecycledAt, v)) +} + +// RecycledAtGTE applies the GTE predicate on the "recycled_at" field. +func RecycledAtGTE(v time.Time) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldGTE(FieldRecycledAt, v)) +} + +// RecycledAtLT applies the LT predicate on the "recycled_at" field. +func RecycledAtLT(v time.Time) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldLT(FieldRecycledAt, v)) +} + +// RecycledAtLTE applies the LTE predicate on the "recycled_at" field. +func RecycledAtLTE(v time.Time) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldLTE(FieldRecycledAt, v)) +} + +// CreatedAtEQ applies the EQ predicate on the "created_at" field. +func CreatedAtEQ(v time.Time) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldEQ(FieldCreatedAt, v)) +} + +// CreatedAtNEQ applies the NEQ predicate on the "created_at" field. +func CreatedAtNEQ(v time.Time) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldNEQ(FieldCreatedAt, v)) +} + +// CreatedAtIn applies the In predicate on the "created_at" field. +func CreatedAtIn(vs ...time.Time) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldIn(FieldCreatedAt, vs...)) +} + +// CreatedAtNotIn applies the NotIn predicate on the "created_at" field. +func CreatedAtNotIn(vs ...time.Time) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldNotIn(FieldCreatedAt, vs...)) +} + +// CreatedAtGT applies the GT predicate on the "created_at" field. +func CreatedAtGT(v time.Time) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldGT(FieldCreatedAt, v)) +} + +// CreatedAtGTE applies the GTE predicate on the "created_at" field. +func CreatedAtGTE(v time.Time) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldGTE(FieldCreatedAt, v)) +} + +// CreatedAtLT applies the LT predicate on the "created_at" field. +func CreatedAtLT(v time.Time) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldLT(FieldCreatedAt, v)) +} + +// CreatedAtLTE applies the LTE predicate on the "created_at" field. +func CreatedAtLTE(v time.Time) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.FieldLTE(FieldCreatedAt, v)) +} + +// And groups predicates with the AND operator between them. +func And(predicates ...predicate.VirtualMachineRecycleRecord) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.AndPredicates(predicates...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.VirtualMachineRecycleRecord) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.VirtualMachineRecycleRecord) predicate.VirtualMachineRecycleRecord { + return predicate.VirtualMachineRecycleRecord(sql.NotPredicates(p)) +} diff --git a/backend/db/virtualmachinerecyclerecord_create.go b/backend/db/virtualmachinerecyclerecord_create.go new file mode 100644 index 000000000..18009ffee --- /dev/null +++ b/backend/db/virtualmachinerecyclerecord_create.go @@ -0,0 +1,971 @@ +// Code generated by ent, DO NOT EDIT. + +package db + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/chaitin/MonkeyCode/backend/consts" + "github.com/chaitin/MonkeyCode/backend/db/virtualmachinerecyclerecord" + "github.com/google/uuid" +) + +// VirtualMachineRecycleRecordCreate is the builder for creating a VirtualMachineRecycleRecord entity. +type VirtualMachineRecycleRecordCreate struct { + config + mutation *VirtualMachineRecycleRecordMutation + hooks []Hook + conflict []sql.ConflictOption +} + +// SetVirtualmachineID sets the "virtualmachine_id" field. +func (_c *VirtualMachineRecycleRecordCreate) SetVirtualmachineID(v string) *VirtualMachineRecycleRecordCreate { + _c.mutation.SetVirtualmachineID(v) + return _c +} + +// SetEnvironmentID sets the "environment_id" field. +func (_c *VirtualMachineRecycleRecordCreate) SetEnvironmentID(v string) *VirtualMachineRecycleRecordCreate { + _c.mutation.SetEnvironmentID(v) + return _c +} + +// SetHostID sets the "host_id" field. +func (_c *VirtualMachineRecycleRecordCreate) SetHostID(v string) *VirtualMachineRecycleRecordCreate { + _c.mutation.SetHostID(v) + return _c +} + +// SetUserID sets the "user_id" field. +func (_c *VirtualMachineRecycleRecordCreate) SetUserID(v uuid.UUID) *VirtualMachineRecycleRecordCreate { + _c.mutation.SetUserID(v) + return _c +} + +// SetNillableUserID sets the "user_id" field if the given value is not nil. +func (_c *VirtualMachineRecycleRecordCreate) SetNillableUserID(v *uuid.UUID) *VirtualMachineRecycleRecordCreate { + if v != nil { + _c.SetUserID(*v) + } + return _c +} + +// SetTaskIds sets the "task_ids" field. +func (_c *VirtualMachineRecycleRecordCreate) SetTaskIds(v []uuid.UUID) *VirtualMachineRecycleRecordCreate { + _c.mutation.SetTaskIds(v) + return _c +} + +// SetMethod sets the "method" field. +func (_c *VirtualMachineRecycleRecordCreate) SetMethod(v consts.VMRecycleMethod) *VirtualMachineRecycleRecordCreate { + _c.mutation.SetMethod(v) + return _c +} + +// SetRemoteDeleted sets the "remote_deleted" field. +func (_c *VirtualMachineRecycleRecordCreate) SetRemoteDeleted(v bool) *VirtualMachineRecycleRecordCreate { + _c.mutation.SetRemoteDeleted(v) + return _c +} + +// SetNillableRemoteDeleted sets the "remote_deleted" field if the given value is not nil. +func (_c *VirtualMachineRecycleRecordCreate) SetNillableRemoteDeleted(v *bool) *VirtualMachineRecycleRecordCreate { + if v != nil { + _c.SetRemoteDeleted(*v) + } + return _c +} + +// SetRecycledAt sets the "recycled_at" field. +func (_c *VirtualMachineRecycleRecordCreate) SetRecycledAt(v time.Time) *VirtualMachineRecycleRecordCreate { + _c.mutation.SetRecycledAt(v) + return _c +} + +// SetCreatedAt sets the "created_at" field. +func (_c *VirtualMachineRecycleRecordCreate) SetCreatedAt(v time.Time) *VirtualMachineRecycleRecordCreate { + _c.mutation.SetCreatedAt(v) + return _c +} + +// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. +func (_c *VirtualMachineRecycleRecordCreate) SetNillableCreatedAt(v *time.Time) *VirtualMachineRecycleRecordCreate { + if v != nil { + _c.SetCreatedAt(*v) + } + return _c +} + +// SetID sets the "id" field. +func (_c *VirtualMachineRecycleRecordCreate) SetID(v uuid.UUID) *VirtualMachineRecycleRecordCreate { + _c.mutation.SetID(v) + return _c +} + +// Mutation returns the VirtualMachineRecycleRecordMutation object of the builder. +func (_c *VirtualMachineRecycleRecordCreate) Mutation() *VirtualMachineRecycleRecordMutation { + return _c.mutation +} + +// Save creates the VirtualMachineRecycleRecord in the database. +func (_c *VirtualMachineRecycleRecordCreate) Save(ctx context.Context) (*VirtualMachineRecycleRecord, error) { + _c.defaults() + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (_c *VirtualMachineRecycleRecordCreate) SaveX(ctx context.Context) *VirtualMachineRecycleRecord { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *VirtualMachineRecycleRecordCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *VirtualMachineRecycleRecordCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (_c *VirtualMachineRecycleRecordCreate) defaults() { + if _, ok := _c.mutation.RemoteDeleted(); !ok { + v := virtualmachinerecyclerecord.DefaultRemoteDeleted + _c.mutation.SetRemoteDeleted(v) + } + if _, ok := _c.mutation.CreatedAt(); !ok { + v := virtualmachinerecyclerecord.DefaultCreatedAt() + _c.mutation.SetCreatedAt(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_c *VirtualMachineRecycleRecordCreate) check() error { + if _, ok := _c.mutation.VirtualmachineID(); !ok { + return &ValidationError{Name: "virtualmachine_id", err: errors.New(`db: missing required field "VirtualMachineRecycleRecord.virtualmachine_id"`)} + } + if _, ok := _c.mutation.EnvironmentID(); !ok { + return &ValidationError{Name: "environment_id", err: errors.New(`db: missing required field "VirtualMachineRecycleRecord.environment_id"`)} + } + if _, ok := _c.mutation.HostID(); !ok { + return &ValidationError{Name: "host_id", err: errors.New(`db: missing required field "VirtualMachineRecycleRecord.host_id"`)} + } + if _, ok := _c.mutation.TaskIds(); !ok { + return &ValidationError{Name: "task_ids", err: errors.New(`db: missing required field "VirtualMachineRecycleRecord.task_ids"`)} + } + if _, ok := _c.mutation.Method(); !ok { + return &ValidationError{Name: "method", err: errors.New(`db: missing required field "VirtualMachineRecycleRecord.method"`)} + } + if _, ok := _c.mutation.RemoteDeleted(); !ok { + return &ValidationError{Name: "remote_deleted", err: errors.New(`db: missing required field "VirtualMachineRecycleRecord.remote_deleted"`)} + } + if _, ok := _c.mutation.RecycledAt(); !ok { + return &ValidationError{Name: "recycled_at", err: errors.New(`db: missing required field "VirtualMachineRecycleRecord.recycled_at"`)} + } + if _, ok := _c.mutation.CreatedAt(); !ok { + return &ValidationError{Name: "created_at", err: errors.New(`db: missing required field "VirtualMachineRecycleRecord.created_at"`)} + } + return nil +} + +func (_c *VirtualMachineRecycleRecordCreate) sqlSave(ctx context.Context) (*VirtualMachineRecycleRecord, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + if _spec.ID.Value != nil { + if id, ok := _spec.ID.Value.(*uuid.UUID); ok { + _node.ID = *id + } else if err := _node.ID.Scan(_spec.ID.Value); err != nil { + return nil, err + } + } + _c.mutation.id = &_node.ID + _c.mutation.done = true + return _node, nil +} + +func (_c *VirtualMachineRecycleRecordCreate) createSpec() (*VirtualMachineRecycleRecord, *sqlgraph.CreateSpec) { + var ( + _node = &VirtualMachineRecycleRecord{config: _c.config} + _spec = sqlgraph.NewCreateSpec(virtualmachinerecyclerecord.Table, sqlgraph.NewFieldSpec(virtualmachinerecyclerecord.FieldID, field.TypeUUID)) + ) + _spec.OnConflict = _c.conflict + if id, ok := _c.mutation.ID(); ok { + _node.ID = id + _spec.ID.Value = &id + } + if value, ok := _c.mutation.VirtualmachineID(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldVirtualmachineID, field.TypeString, value) + _node.VirtualmachineID = value + } + if value, ok := _c.mutation.EnvironmentID(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldEnvironmentID, field.TypeString, value) + _node.EnvironmentID = value + } + if value, ok := _c.mutation.HostID(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldHostID, field.TypeString, value) + _node.HostID = value + } + if value, ok := _c.mutation.UserID(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldUserID, field.TypeUUID, value) + _node.UserID = &value + } + if value, ok := _c.mutation.TaskIds(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldTaskIds, field.TypeJSON, value) + _node.TaskIds = value + } + if value, ok := _c.mutation.Method(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldMethod, field.TypeString, value) + _node.Method = value + } + if value, ok := _c.mutation.RemoteDeleted(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldRemoteDeleted, field.TypeBool, value) + _node.RemoteDeleted = value + } + if value, ok := _c.mutation.RecycledAt(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldRecycledAt, field.TypeTime, value) + _node.RecycledAt = value + } + if value, ok := _c.mutation.CreatedAt(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldCreatedAt, field.TypeTime, value) + _node.CreatedAt = value + } + return _node, _spec +} + +// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause +// of the `INSERT` statement. For example: +// +// client.VirtualMachineRecycleRecord.Create(). +// SetVirtualmachineID(v). +// OnConflict( +// // Update the row with the new values +// // the was proposed for insertion. +// sql.ResolveWithNewValues(), +// ). +// // Override some of the fields with custom +// // update values. +// Update(func(u *ent.VirtualMachineRecycleRecordUpsert) { +// SetVirtualmachineID(v+v). +// }). +// Exec(ctx) +func (_c *VirtualMachineRecycleRecordCreate) OnConflict(opts ...sql.ConflictOption) *VirtualMachineRecycleRecordUpsertOne { + _c.conflict = opts + return &VirtualMachineRecycleRecordUpsertOne{ + create: _c, + } +} + +// OnConflictColumns calls `OnConflict` and configures the columns +// as conflict target. Using this option is equivalent to using: +// +// client.VirtualMachineRecycleRecord.Create(). +// OnConflict(sql.ConflictColumns(columns...)). +// Exec(ctx) +func (_c *VirtualMachineRecycleRecordCreate) OnConflictColumns(columns ...string) *VirtualMachineRecycleRecordUpsertOne { + _c.conflict = append(_c.conflict, sql.ConflictColumns(columns...)) + return &VirtualMachineRecycleRecordUpsertOne{ + create: _c, + } +} + +type ( + // VirtualMachineRecycleRecordUpsertOne is the builder for "upsert"-ing + // one VirtualMachineRecycleRecord node. + VirtualMachineRecycleRecordUpsertOne struct { + create *VirtualMachineRecycleRecordCreate + } + + // VirtualMachineRecycleRecordUpsert is the "OnConflict" setter. + VirtualMachineRecycleRecordUpsert struct { + *sql.UpdateSet + } +) + +// SetVirtualmachineID sets the "virtualmachine_id" field. +func (u *VirtualMachineRecycleRecordUpsert) SetVirtualmachineID(v string) *VirtualMachineRecycleRecordUpsert { + u.Set(virtualmachinerecyclerecord.FieldVirtualmachineID, v) + return u +} + +// UpdateVirtualmachineID sets the "virtualmachine_id" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsert) UpdateVirtualmachineID() *VirtualMachineRecycleRecordUpsert { + u.SetExcluded(virtualmachinerecyclerecord.FieldVirtualmachineID) + return u +} + +// SetEnvironmentID sets the "environment_id" field. +func (u *VirtualMachineRecycleRecordUpsert) SetEnvironmentID(v string) *VirtualMachineRecycleRecordUpsert { + u.Set(virtualmachinerecyclerecord.FieldEnvironmentID, v) + return u +} + +// UpdateEnvironmentID sets the "environment_id" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsert) UpdateEnvironmentID() *VirtualMachineRecycleRecordUpsert { + u.SetExcluded(virtualmachinerecyclerecord.FieldEnvironmentID) + return u +} + +// SetHostID sets the "host_id" field. +func (u *VirtualMachineRecycleRecordUpsert) SetHostID(v string) *VirtualMachineRecycleRecordUpsert { + u.Set(virtualmachinerecyclerecord.FieldHostID, v) + return u +} + +// UpdateHostID sets the "host_id" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsert) UpdateHostID() *VirtualMachineRecycleRecordUpsert { + u.SetExcluded(virtualmachinerecyclerecord.FieldHostID) + return u +} + +// SetUserID sets the "user_id" field. +func (u *VirtualMachineRecycleRecordUpsert) SetUserID(v uuid.UUID) *VirtualMachineRecycleRecordUpsert { + u.Set(virtualmachinerecyclerecord.FieldUserID, v) + return u +} + +// UpdateUserID sets the "user_id" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsert) UpdateUserID() *VirtualMachineRecycleRecordUpsert { + u.SetExcluded(virtualmachinerecyclerecord.FieldUserID) + return u +} + +// ClearUserID clears the value of the "user_id" field. +func (u *VirtualMachineRecycleRecordUpsert) ClearUserID() *VirtualMachineRecycleRecordUpsert { + u.SetNull(virtualmachinerecyclerecord.FieldUserID) + return u +} + +// SetTaskIds sets the "task_ids" field. +func (u *VirtualMachineRecycleRecordUpsert) SetTaskIds(v []uuid.UUID) *VirtualMachineRecycleRecordUpsert { + u.Set(virtualmachinerecyclerecord.FieldTaskIds, v) + return u +} + +// UpdateTaskIds sets the "task_ids" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsert) UpdateTaskIds() *VirtualMachineRecycleRecordUpsert { + u.SetExcluded(virtualmachinerecyclerecord.FieldTaskIds) + return u +} + +// SetMethod sets the "method" field. +func (u *VirtualMachineRecycleRecordUpsert) SetMethod(v consts.VMRecycleMethod) *VirtualMachineRecycleRecordUpsert { + u.Set(virtualmachinerecyclerecord.FieldMethod, v) + return u +} + +// UpdateMethod sets the "method" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsert) UpdateMethod() *VirtualMachineRecycleRecordUpsert { + u.SetExcluded(virtualmachinerecyclerecord.FieldMethod) + return u +} + +// SetRemoteDeleted sets the "remote_deleted" field. +func (u *VirtualMachineRecycleRecordUpsert) SetRemoteDeleted(v bool) *VirtualMachineRecycleRecordUpsert { + u.Set(virtualmachinerecyclerecord.FieldRemoteDeleted, v) + return u +} + +// UpdateRemoteDeleted sets the "remote_deleted" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsert) UpdateRemoteDeleted() *VirtualMachineRecycleRecordUpsert { + u.SetExcluded(virtualmachinerecyclerecord.FieldRemoteDeleted) + return u +} + +// SetRecycledAt sets the "recycled_at" field. +func (u *VirtualMachineRecycleRecordUpsert) SetRecycledAt(v time.Time) *VirtualMachineRecycleRecordUpsert { + u.Set(virtualmachinerecyclerecord.FieldRecycledAt, v) + return u +} + +// UpdateRecycledAt sets the "recycled_at" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsert) UpdateRecycledAt() *VirtualMachineRecycleRecordUpsert { + u.SetExcluded(virtualmachinerecyclerecord.FieldRecycledAt) + return u +} + +// SetCreatedAt sets the "created_at" field. +func (u *VirtualMachineRecycleRecordUpsert) SetCreatedAt(v time.Time) *VirtualMachineRecycleRecordUpsert { + u.Set(virtualmachinerecyclerecord.FieldCreatedAt, v) + return u +} + +// UpdateCreatedAt sets the "created_at" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsert) UpdateCreatedAt() *VirtualMachineRecycleRecordUpsert { + u.SetExcluded(virtualmachinerecyclerecord.FieldCreatedAt) + return u +} + +// UpdateNewValues updates the mutable fields using the new values that were set on create except the ID field. +// Using this option is equivalent to using: +// +// client.VirtualMachineRecycleRecord.Create(). +// OnConflict( +// sql.ResolveWithNewValues(), +// sql.ResolveWith(func(u *sql.UpdateSet) { +// u.SetIgnore(virtualmachinerecyclerecord.FieldID) +// }), +// ). +// Exec(ctx) +func (u *VirtualMachineRecycleRecordUpsertOne) UpdateNewValues() *VirtualMachineRecycleRecordUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues()) + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) { + if _, exists := u.create.mutation.ID(); exists { + s.SetIgnore(virtualmachinerecyclerecord.FieldID) + } + })) + return u +} + +// Ignore sets each column to itself in case of conflict. +// Using this option is equivalent to using: +// +// client.VirtualMachineRecycleRecord.Create(). +// OnConflict(sql.ResolveWithIgnore()). +// Exec(ctx) +func (u *VirtualMachineRecycleRecordUpsertOne) Ignore() *VirtualMachineRecycleRecordUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore()) + return u +} + +// DoNothing configures the conflict_action to `DO NOTHING`. +// Supported only by SQLite and PostgreSQL. +func (u *VirtualMachineRecycleRecordUpsertOne) DoNothing() *VirtualMachineRecycleRecordUpsertOne { + u.create.conflict = append(u.create.conflict, sql.DoNothing()) + return u +} + +// Update allows overriding fields `UPDATE` values. See the VirtualMachineRecycleRecordCreate.OnConflict +// documentation for more info. +func (u *VirtualMachineRecycleRecordUpsertOne) Update(set func(*VirtualMachineRecycleRecordUpsert)) *VirtualMachineRecycleRecordUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) { + set(&VirtualMachineRecycleRecordUpsert{UpdateSet: update}) + })) + return u +} + +// SetVirtualmachineID sets the "virtualmachine_id" field. +func (u *VirtualMachineRecycleRecordUpsertOne) SetVirtualmachineID(v string) *VirtualMachineRecycleRecordUpsertOne { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.SetVirtualmachineID(v) + }) +} + +// UpdateVirtualmachineID sets the "virtualmachine_id" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsertOne) UpdateVirtualmachineID() *VirtualMachineRecycleRecordUpsertOne { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.UpdateVirtualmachineID() + }) +} + +// SetEnvironmentID sets the "environment_id" field. +func (u *VirtualMachineRecycleRecordUpsertOne) SetEnvironmentID(v string) *VirtualMachineRecycleRecordUpsertOne { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.SetEnvironmentID(v) + }) +} + +// UpdateEnvironmentID sets the "environment_id" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsertOne) UpdateEnvironmentID() *VirtualMachineRecycleRecordUpsertOne { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.UpdateEnvironmentID() + }) +} + +// SetHostID sets the "host_id" field. +func (u *VirtualMachineRecycleRecordUpsertOne) SetHostID(v string) *VirtualMachineRecycleRecordUpsertOne { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.SetHostID(v) + }) +} + +// UpdateHostID sets the "host_id" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsertOne) UpdateHostID() *VirtualMachineRecycleRecordUpsertOne { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.UpdateHostID() + }) +} + +// SetUserID sets the "user_id" field. +func (u *VirtualMachineRecycleRecordUpsertOne) SetUserID(v uuid.UUID) *VirtualMachineRecycleRecordUpsertOne { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.SetUserID(v) + }) +} + +// UpdateUserID sets the "user_id" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsertOne) UpdateUserID() *VirtualMachineRecycleRecordUpsertOne { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.UpdateUserID() + }) +} + +// ClearUserID clears the value of the "user_id" field. +func (u *VirtualMachineRecycleRecordUpsertOne) ClearUserID() *VirtualMachineRecycleRecordUpsertOne { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.ClearUserID() + }) +} + +// SetTaskIds sets the "task_ids" field. +func (u *VirtualMachineRecycleRecordUpsertOne) SetTaskIds(v []uuid.UUID) *VirtualMachineRecycleRecordUpsertOne { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.SetTaskIds(v) + }) +} + +// UpdateTaskIds sets the "task_ids" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsertOne) UpdateTaskIds() *VirtualMachineRecycleRecordUpsertOne { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.UpdateTaskIds() + }) +} + +// SetMethod sets the "method" field. +func (u *VirtualMachineRecycleRecordUpsertOne) SetMethod(v consts.VMRecycleMethod) *VirtualMachineRecycleRecordUpsertOne { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.SetMethod(v) + }) +} + +// UpdateMethod sets the "method" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsertOne) UpdateMethod() *VirtualMachineRecycleRecordUpsertOne { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.UpdateMethod() + }) +} + +// SetRemoteDeleted sets the "remote_deleted" field. +func (u *VirtualMachineRecycleRecordUpsertOne) SetRemoteDeleted(v bool) *VirtualMachineRecycleRecordUpsertOne { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.SetRemoteDeleted(v) + }) +} + +// UpdateRemoteDeleted sets the "remote_deleted" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsertOne) UpdateRemoteDeleted() *VirtualMachineRecycleRecordUpsertOne { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.UpdateRemoteDeleted() + }) +} + +// SetRecycledAt sets the "recycled_at" field. +func (u *VirtualMachineRecycleRecordUpsertOne) SetRecycledAt(v time.Time) *VirtualMachineRecycleRecordUpsertOne { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.SetRecycledAt(v) + }) +} + +// UpdateRecycledAt sets the "recycled_at" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsertOne) UpdateRecycledAt() *VirtualMachineRecycleRecordUpsertOne { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.UpdateRecycledAt() + }) +} + +// SetCreatedAt sets the "created_at" field. +func (u *VirtualMachineRecycleRecordUpsertOne) SetCreatedAt(v time.Time) *VirtualMachineRecycleRecordUpsertOne { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.SetCreatedAt(v) + }) +} + +// UpdateCreatedAt sets the "created_at" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsertOne) UpdateCreatedAt() *VirtualMachineRecycleRecordUpsertOne { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.UpdateCreatedAt() + }) +} + +// Exec executes the query. +func (u *VirtualMachineRecycleRecordUpsertOne) Exec(ctx context.Context) error { + if len(u.create.conflict) == 0 { + return errors.New("db: missing options for VirtualMachineRecycleRecordCreate.OnConflict") + } + return u.create.Exec(ctx) +} + +// ExecX is like Exec, but panics if an error occurs. +func (u *VirtualMachineRecycleRecordUpsertOne) ExecX(ctx context.Context) { + if err := u.create.Exec(ctx); err != nil { + panic(err) + } +} + +// Exec executes the UPSERT query and returns the inserted/updated ID. +func (u *VirtualMachineRecycleRecordUpsertOne) ID(ctx context.Context) (id uuid.UUID, err error) { + if u.create.driver.Dialect() == dialect.MySQL { + // In case of "ON CONFLICT", there is no way to get back non-numeric ID + // fields from the database since MySQL does not support the RETURNING clause. + return id, errors.New("db: VirtualMachineRecycleRecordUpsertOne.ID is not supported by MySQL driver. Use VirtualMachineRecycleRecordUpsertOne.Exec instead") + } + node, err := u.create.Save(ctx) + if err != nil { + return id, err + } + return node.ID, nil +} + +// IDX is like ID, but panics if an error occurs. +func (u *VirtualMachineRecycleRecordUpsertOne) IDX(ctx context.Context) uuid.UUID { + id, err := u.ID(ctx) + if err != nil { + panic(err) + } + return id +} + +// VirtualMachineRecycleRecordCreateBulk is the builder for creating many VirtualMachineRecycleRecord entities in bulk. +type VirtualMachineRecycleRecordCreateBulk struct { + config + err error + builders []*VirtualMachineRecycleRecordCreate + conflict []sql.ConflictOption +} + +// Save creates the VirtualMachineRecycleRecord entities in the database. +func (_c *VirtualMachineRecycleRecordCreateBulk) Save(ctx context.Context) ([]*VirtualMachineRecycleRecord, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*VirtualMachineRecycleRecord, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { + func(i int, root context.Context) { + builder := _c.builders[i] + builder.defaults() + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*VirtualMachineRecycleRecordMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.OnConflict = _c.conflict + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (_c *VirtualMachineRecycleRecordCreateBulk) SaveX(ctx context.Context) []*VirtualMachineRecycleRecord { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *VirtualMachineRecycleRecordCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *VirtualMachineRecycleRecordCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause +// of the `INSERT` statement. For example: +// +// client.VirtualMachineRecycleRecord.CreateBulk(builders...). +// OnConflict( +// // Update the row with the new values +// // the was proposed for insertion. +// sql.ResolveWithNewValues(), +// ). +// // Override some of the fields with custom +// // update values. +// Update(func(u *ent.VirtualMachineRecycleRecordUpsert) { +// SetVirtualmachineID(v+v). +// }). +// Exec(ctx) +func (_c *VirtualMachineRecycleRecordCreateBulk) OnConflict(opts ...sql.ConflictOption) *VirtualMachineRecycleRecordUpsertBulk { + _c.conflict = opts + return &VirtualMachineRecycleRecordUpsertBulk{ + create: _c, + } +} + +// OnConflictColumns calls `OnConflict` and configures the columns +// as conflict target. Using this option is equivalent to using: +// +// client.VirtualMachineRecycleRecord.Create(). +// OnConflict(sql.ConflictColumns(columns...)). +// Exec(ctx) +func (_c *VirtualMachineRecycleRecordCreateBulk) OnConflictColumns(columns ...string) *VirtualMachineRecycleRecordUpsertBulk { + _c.conflict = append(_c.conflict, sql.ConflictColumns(columns...)) + return &VirtualMachineRecycleRecordUpsertBulk{ + create: _c, + } +} + +// VirtualMachineRecycleRecordUpsertBulk is the builder for "upsert"-ing +// a bulk of VirtualMachineRecycleRecord nodes. +type VirtualMachineRecycleRecordUpsertBulk struct { + create *VirtualMachineRecycleRecordCreateBulk +} + +// UpdateNewValues updates the mutable fields using the new values that +// were set on create. Using this option is equivalent to using: +// +// client.VirtualMachineRecycleRecord.Create(). +// OnConflict( +// sql.ResolveWithNewValues(), +// sql.ResolveWith(func(u *sql.UpdateSet) { +// u.SetIgnore(virtualmachinerecyclerecord.FieldID) +// }), +// ). +// Exec(ctx) +func (u *VirtualMachineRecycleRecordUpsertBulk) UpdateNewValues() *VirtualMachineRecycleRecordUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues()) + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) { + for _, b := range u.create.builders { + if _, exists := b.mutation.ID(); exists { + s.SetIgnore(virtualmachinerecyclerecord.FieldID) + } + } + })) + return u +} + +// Ignore sets each column to itself in case of conflict. +// Using this option is equivalent to using: +// +// client.VirtualMachineRecycleRecord.Create(). +// OnConflict(sql.ResolveWithIgnore()). +// Exec(ctx) +func (u *VirtualMachineRecycleRecordUpsertBulk) Ignore() *VirtualMachineRecycleRecordUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore()) + return u +} + +// DoNothing configures the conflict_action to `DO NOTHING`. +// Supported only by SQLite and PostgreSQL. +func (u *VirtualMachineRecycleRecordUpsertBulk) DoNothing() *VirtualMachineRecycleRecordUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.DoNothing()) + return u +} + +// Update allows overriding fields `UPDATE` values. See the VirtualMachineRecycleRecordCreateBulk.OnConflict +// documentation for more info. +func (u *VirtualMachineRecycleRecordUpsertBulk) Update(set func(*VirtualMachineRecycleRecordUpsert)) *VirtualMachineRecycleRecordUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) { + set(&VirtualMachineRecycleRecordUpsert{UpdateSet: update}) + })) + return u +} + +// SetVirtualmachineID sets the "virtualmachine_id" field. +func (u *VirtualMachineRecycleRecordUpsertBulk) SetVirtualmachineID(v string) *VirtualMachineRecycleRecordUpsertBulk { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.SetVirtualmachineID(v) + }) +} + +// UpdateVirtualmachineID sets the "virtualmachine_id" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsertBulk) UpdateVirtualmachineID() *VirtualMachineRecycleRecordUpsertBulk { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.UpdateVirtualmachineID() + }) +} + +// SetEnvironmentID sets the "environment_id" field. +func (u *VirtualMachineRecycleRecordUpsertBulk) SetEnvironmentID(v string) *VirtualMachineRecycleRecordUpsertBulk { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.SetEnvironmentID(v) + }) +} + +// UpdateEnvironmentID sets the "environment_id" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsertBulk) UpdateEnvironmentID() *VirtualMachineRecycleRecordUpsertBulk { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.UpdateEnvironmentID() + }) +} + +// SetHostID sets the "host_id" field. +func (u *VirtualMachineRecycleRecordUpsertBulk) SetHostID(v string) *VirtualMachineRecycleRecordUpsertBulk { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.SetHostID(v) + }) +} + +// UpdateHostID sets the "host_id" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsertBulk) UpdateHostID() *VirtualMachineRecycleRecordUpsertBulk { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.UpdateHostID() + }) +} + +// SetUserID sets the "user_id" field. +func (u *VirtualMachineRecycleRecordUpsertBulk) SetUserID(v uuid.UUID) *VirtualMachineRecycleRecordUpsertBulk { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.SetUserID(v) + }) +} + +// UpdateUserID sets the "user_id" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsertBulk) UpdateUserID() *VirtualMachineRecycleRecordUpsertBulk { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.UpdateUserID() + }) +} + +// ClearUserID clears the value of the "user_id" field. +func (u *VirtualMachineRecycleRecordUpsertBulk) ClearUserID() *VirtualMachineRecycleRecordUpsertBulk { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.ClearUserID() + }) +} + +// SetTaskIds sets the "task_ids" field. +func (u *VirtualMachineRecycleRecordUpsertBulk) SetTaskIds(v []uuid.UUID) *VirtualMachineRecycleRecordUpsertBulk { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.SetTaskIds(v) + }) +} + +// UpdateTaskIds sets the "task_ids" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsertBulk) UpdateTaskIds() *VirtualMachineRecycleRecordUpsertBulk { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.UpdateTaskIds() + }) +} + +// SetMethod sets the "method" field. +func (u *VirtualMachineRecycleRecordUpsertBulk) SetMethod(v consts.VMRecycleMethod) *VirtualMachineRecycleRecordUpsertBulk { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.SetMethod(v) + }) +} + +// UpdateMethod sets the "method" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsertBulk) UpdateMethod() *VirtualMachineRecycleRecordUpsertBulk { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.UpdateMethod() + }) +} + +// SetRemoteDeleted sets the "remote_deleted" field. +func (u *VirtualMachineRecycleRecordUpsertBulk) SetRemoteDeleted(v bool) *VirtualMachineRecycleRecordUpsertBulk { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.SetRemoteDeleted(v) + }) +} + +// UpdateRemoteDeleted sets the "remote_deleted" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsertBulk) UpdateRemoteDeleted() *VirtualMachineRecycleRecordUpsertBulk { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.UpdateRemoteDeleted() + }) +} + +// SetRecycledAt sets the "recycled_at" field. +func (u *VirtualMachineRecycleRecordUpsertBulk) SetRecycledAt(v time.Time) *VirtualMachineRecycleRecordUpsertBulk { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.SetRecycledAt(v) + }) +} + +// UpdateRecycledAt sets the "recycled_at" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsertBulk) UpdateRecycledAt() *VirtualMachineRecycleRecordUpsertBulk { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.UpdateRecycledAt() + }) +} + +// SetCreatedAt sets the "created_at" field. +func (u *VirtualMachineRecycleRecordUpsertBulk) SetCreatedAt(v time.Time) *VirtualMachineRecycleRecordUpsertBulk { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.SetCreatedAt(v) + }) +} + +// UpdateCreatedAt sets the "created_at" field to the value that was provided on create. +func (u *VirtualMachineRecycleRecordUpsertBulk) UpdateCreatedAt() *VirtualMachineRecycleRecordUpsertBulk { + return u.Update(func(s *VirtualMachineRecycleRecordUpsert) { + s.UpdateCreatedAt() + }) +} + +// Exec executes the query. +func (u *VirtualMachineRecycleRecordUpsertBulk) Exec(ctx context.Context) error { + if u.create.err != nil { + return u.create.err + } + for i, b := range u.create.builders { + if len(b.conflict) != 0 { + return fmt.Errorf("db: OnConflict was set for builder %d. Set it on the VirtualMachineRecycleRecordCreateBulk instead", i) + } + } + if len(u.create.conflict) == 0 { + return errors.New("db: missing options for VirtualMachineRecycleRecordCreateBulk.OnConflict") + } + return u.create.Exec(ctx) +} + +// ExecX is like Exec, but panics if an error occurs. +func (u *VirtualMachineRecycleRecordUpsertBulk) ExecX(ctx context.Context) { + if err := u.create.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/backend/db/virtualmachinerecyclerecord_delete.go b/backend/db/virtualmachinerecyclerecord_delete.go new file mode 100644 index 000000000..a908c667b --- /dev/null +++ b/backend/db/virtualmachinerecyclerecord_delete.go @@ -0,0 +1,88 @@ +// Code generated by ent, DO NOT EDIT. + +package db + +import ( + "context" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/chaitin/MonkeyCode/backend/db/predicate" + "github.com/chaitin/MonkeyCode/backend/db/virtualmachinerecyclerecord" +) + +// VirtualMachineRecycleRecordDelete is the builder for deleting a VirtualMachineRecycleRecord entity. +type VirtualMachineRecycleRecordDelete struct { + config + hooks []Hook + mutation *VirtualMachineRecycleRecordMutation +} + +// Where appends a list predicates to the VirtualMachineRecycleRecordDelete builder. +func (_d *VirtualMachineRecycleRecordDelete) Where(ps ...predicate.VirtualMachineRecycleRecord) *VirtualMachineRecycleRecordDelete { + _d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (_d *VirtualMachineRecycleRecordDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *VirtualMachineRecycleRecordDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (_d *VirtualMachineRecycleRecordDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(virtualmachinerecyclerecord.Table, sqlgraph.NewFieldSpec(virtualmachinerecyclerecord.FieldID, field.TypeUUID)) + if ps := _d.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + _d.mutation.done = true + return affected, err +} + +// VirtualMachineRecycleRecordDeleteOne is the builder for deleting a single VirtualMachineRecycleRecord entity. +type VirtualMachineRecycleRecordDeleteOne struct { + _d *VirtualMachineRecycleRecordDelete +} + +// Where appends a list predicates to the VirtualMachineRecycleRecordDelete builder. +func (_d *VirtualMachineRecycleRecordDeleteOne) Where(ps ...predicate.VirtualMachineRecycleRecord) *VirtualMachineRecycleRecordDeleteOne { + _d._d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query. +func (_d *VirtualMachineRecycleRecordDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{virtualmachinerecyclerecord.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *VirtualMachineRecycleRecordDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/backend/db/virtualmachinerecyclerecord_query.go b/backend/db/virtualmachinerecyclerecord_query.go new file mode 100644 index 000000000..d678d87a5 --- /dev/null +++ b/backend/db/virtualmachinerecyclerecord_query.go @@ -0,0 +1,578 @@ +// Code generated by ent, DO NOT EDIT. + +package db + +import ( + "context" + "fmt" + "math" + + "entgo.io/ent" + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/chaitin/MonkeyCode/backend/db/predicate" + "github.com/chaitin/MonkeyCode/backend/db/virtualmachinerecyclerecord" + "github.com/google/uuid" +) + +// VirtualMachineRecycleRecordQuery is the builder for querying VirtualMachineRecycleRecord entities. +type VirtualMachineRecycleRecordQuery struct { + config + ctx *QueryContext + order []virtualmachinerecyclerecord.OrderOption + inters []Interceptor + predicates []predicate.VirtualMachineRecycleRecord + modifiers []func(*sql.Selector) + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the VirtualMachineRecycleRecordQuery builder. +func (_q *VirtualMachineRecycleRecordQuery) Where(ps ...predicate.VirtualMachineRecycleRecord) *VirtualMachineRecycleRecordQuery { + _q.predicates = append(_q.predicates, ps...) + return _q +} + +// Limit the number of records to be returned by this query. +func (_q *VirtualMachineRecycleRecordQuery) Limit(limit int) *VirtualMachineRecycleRecordQuery { + _q.ctx.Limit = &limit + return _q +} + +// Offset to start from. +func (_q *VirtualMachineRecycleRecordQuery) Offset(offset int) *VirtualMachineRecycleRecordQuery { + _q.ctx.Offset = &offset + return _q +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (_q *VirtualMachineRecycleRecordQuery) Unique(unique bool) *VirtualMachineRecycleRecordQuery { + _q.ctx.Unique = &unique + return _q +} + +// Order specifies how the records should be ordered. +func (_q *VirtualMachineRecycleRecordQuery) Order(o ...virtualmachinerecyclerecord.OrderOption) *VirtualMachineRecycleRecordQuery { + _q.order = append(_q.order, o...) + return _q +} + +// First returns the first VirtualMachineRecycleRecord entity from the query. +// Returns a *NotFoundError when no VirtualMachineRecycleRecord was found. +func (_q *VirtualMachineRecycleRecordQuery) First(ctx context.Context) (*VirtualMachineRecycleRecord, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{virtualmachinerecyclerecord.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (_q *VirtualMachineRecycleRecordQuery) FirstX(ctx context.Context) *VirtualMachineRecycleRecord { + node, err := _q.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first VirtualMachineRecycleRecord ID from the query. +// Returns a *NotFoundError when no VirtualMachineRecycleRecord ID was found. +func (_q *VirtualMachineRecycleRecordQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) { + var ids []uuid.UUID + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{virtualmachinerecyclerecord.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (_q *VirtualMachineRecycleRecordQuery) FirstIDX(ctx context.Context) uuid.UUID { + id, err := _q.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single VirtualMachineRecycleRecord entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one VirtualMachineRecycleRecord entity is found. +// Returns a *NotFoundError when no VirtualMachineRecycleRecord entities are found. +func (_q *VirtualMachineRecycleRecordQuery) Only(ctx context.Context) (*VirtualMachineRecycleRecord, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{virtualmachinerecyclerecord.Label} + default: + return nil, &NotSingularError{virtualmachinerecyclerecord.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (_q *VirtualMachineRecycleRecordQuery) OnlyX(ctx context.Context) *VirtualMachineRecycleRecord { + node, err := _q.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only VirtualMachineRecycleRecord ID in the query. +// Returns a *NotSingularError when more than one VirtualMachineRecycleRecord ID is found. +// Returns a *NotFoundError when no entities are found. +func (_q *VirtualMachineRecycleRecordQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) { + var ids []uuid.UUID + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{virtualmachinerecyclerecord.Label} + default: + err = &NotSingularError{virtualmachinerecyclerecord.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (_q *VirtualMachineRecycleRecordQuery) OnlyIDX(ctx context.Context) uuid.UUID { + id, err := _q.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of VirtualMachineRecycleRecords. +func (_q *VirtualMachineRecycleRecordQuery) All(ctx context.Context) ([]*VirtualMachineRecycleRecord, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*VirtualMachineRecycleRecord, *VirtualMachineRecycleRecordQuery]() + return withInterceptors[[]*VirtualMachineRecycleRecord](ctx, _q, qr, _q.inters) +} + +// AllX is like All, but panics if an error occurs. +func (_q *VirtualMachineRecycleRecordQuery) AllX(ctx context.Context) []*VirtualMachineRecycleRecord { + nodes, err := _q.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of VirtualMachineRecycleRecord IDs. +func (_q *VirtualMachineRecycleRecordQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(virtualmachinerecyclerecord.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (_q *VirtualMachineRecycleRecordQuery) IDsX(ctx context.Context) []uuid.UUID { + ids, err := _q.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (_q *VirtualMachineRecycleRecordQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, _q, querierCount[*VirtualMachineRecycleRecordQuery](), _q.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (_q *VirtualMachineRecycleRecordQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (_q *VirtualMachineRecycleRecordQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("db: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (_q *VirtualMachineRecycleRecordQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the VirtualMachineRecycleRecordQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (_q *VirtualMachineRecycleRecordQuery) Clone() *VirtualMachineRecycleRecordQuery { + if _q == nil { + return nil + } + return &VirtualMachineRecycleRecordQuery{ + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]virtualmachinerecyclerecord.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.VirtualMachineRecycleRecord{}, _q.predicates...), + // clone intermediate query. + sql: _q.sql.Clone(), + path: _q.path, + modifiers: append([]func(*sql.Selector){}, _q.modifiers...), + } +} + +// GroupBy is used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// VirtualmachineID string `json:"virtualmachine_id,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.VirtualMachineRecycleRecord.Query(). +// GroupBy(virtualmachinerecyclerecord.FieldVirtualmachineID). +// Aggregate(db.Count()). +// Scan(ctx, &v) +func (_q *VirtualMachineRecycleRecordQuery) GroupBy(field string, fields ...string) *VirtualMachineRecycleRecordGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &VirtualMachineRecycleRecordGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields + grbuild.label = virtualmachinerecyclerecord.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// Select allows the selection one or more fields/columns for the given query, +// instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// VirtualmachineID string `json:"virtualmachine_id,omitempty"` +// } +// +// client.VirtualMachineRecycleRecord.Query(). +// Select(virtualmachinerecyclerecord.FieldVirtualmachineID). +// Scan(ctx, &v) +func (_q *VirtualMachineRecycleRecordQuery) Select(fields ...string) *VirtualMachineRecycleRecordSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &VirtualMachineRecycleRecordSelect{VirtualMachineRecycleRecordQuery: _q} + sbuild.label = virtualmachinerecyclerecord.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a VirtualMachineRecycleRecordSelect configured with the given aggregations. +func (_q *VirtualMachineRecycleRecordQuery) Aggregate(fns ...AggregateFunc) *VirtualMachineRecycleRecordSelect { + return _q.Select().Aggregate(fns...) +} + +func (_q *VirtualMachineRecycleRecordQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("db: uninitialized interceptor (forgotten import db/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { + if !virtualmachinerecyclerecord.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("db: invalid field %q for query", f)} + } + } + if _q.path != nil { + prev, err := _q.path(ctx) + if err != nil { + return err + } + _q.sql = prev + } + return nil +} + +func (_q *VirtualMachineRecycleRecordQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*VirtualMachineRecycleRecord, error) { + var ( + nodes = []*VirtualMachineRecycleRecord{} + _spec = _q.querySpec() + ) + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*VirtualMachineRecycleRecord).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &VirtualMachineRecycleRecord{config: _q.config} + nodes = append(nodes, node) + return node.assignValues(columns, values) + } + if len(_q.modifiers) > 0 { + _spec.Modifiers = _q.modifiers + } + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + return nodes, nil +} + +func (_q *VirtualMachineRecycleRecordQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + if len(_q.modifiers) > 0 { + _spec.Modifiers = _q.modifiers + } + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique + } + return sqlgraph.CountNodes(ctx, _q.driver, _spec) +} + +func (_q *VirtualMachineRecycleRecordQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(virtualmachinerecyclerecord.Table, virtualmachinerecyclerecord.Columns, sqlgraph.NewFieldSpec(virtualmachinerecyclerecord.FieldID, field.TypeUUID)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true + } + if fields := _q.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, virtualmachinerecyclerecord.FieldID) + for i := range fields { + if fields[i] != virtualmachinerecyclerecord.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + } + if ps := _q.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := _q.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := _q.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := _q.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (_q *VirtualMachineRecycleRecordQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) + t1 := builder.Table(virtualmachinerecyclerecord.Table) + columns := _q.ctx.Fields + if len(columns) == 0 { + columns = virtualmachinerecyclerecord.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if _q.sql != nil { + selector = _q.sql + selector.Select(selector.Columns(columns...)...) + } + if _q.ctx.Unique != nil && *_q.ctx.Unique { + selector.Distinct() + } + for _, m := range _q.modifiers { + m(selector) + } + for _, p := range _q.predicates { + p(selector) + } + for _, p := range _q.order { + p(selector) + } + if offset := _q.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := _q.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// ForUpdate locks the selected rows against concurrent updates, and prevent them from being +// updated, deleted or "selected ... for update" by other sessions, until the transaction is +// either committed or rolled-back. +func (_q *VirtualMachineRecycleRecordQuery) ForUpdate(opts ...sql.LockOption) *VirtualMachineRecycleRecordQuery { + if _q.driver.Dialect() == dialect.Postgres { + _q.Unique(false) + } + _q.modifiers = append(_q.modifiers, func(s *sql.Selector) { + s.ForUpdate(opts...) + }) + return _q +} + +// ForShare behaves similarly to ForUpdate, except that it acquires a shared mode lock +// on any rows that are read. Other sessions can read the rows, but cannot modify them +// until your transaction commits. +func (_q *VirtualMachineRecycleRecordQuery) ForShare(opts ...sql.LockOption) *VirtualMachineRecycleRecordQuery { + if _q.driver.Dialect() == dialect.Postgres { + _q.Unique(false) + } + _q.modifiers = append(_q.modifiers, func(s *sql.Selector) { + s.ForShare(opts...) + }) + return _q +} + +// Modify adds a query modifier for attaching custom logic to queries. +func (_q *VirtualMachineRecycleRecordQuery) Modify(modifiers ...func(s *sql.Selector)) *VirtualMachineRecycleRecordSelect { + _q.modifiers = append(_q.modifiers, modifiers...) + return _q.Select() +} + +// VirtualMachineRecycleRecordGroupBy is the group-by builder for VirtualMachineRecycleRecord entities. +type VirtualMachineRecycleRecordGroupBy struct { + selector + build *VirtualMachineRecycleRecordQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (_g *VirtualMachineRecycleRecordGroupBy) Aggregate(fns ...AggregateFunc) *VirtualMachineRecycleRecordGroupBy { + _g.fns = append(_g.fns, fns...) + return _g +} + +// Scan applies the selector query and scans the result into the given value. +func (_g *VirtualMachineRecycleRecordGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*VirtualMachineRecycleRecordQuery, *VirtualMachineRecycleRecordGroupBy](ctx, _g.build, _g, _g.build.inters, v) +} + +func (_g *VirtualMachineRecycleRecordGroupBy) sqlScan(ctx context.Context, root *VirtualMachineRecycleRecordQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*_g.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// VirtualMachineRecycleRecordSelect is the builder for selecting fields of VirtualMachineRecycleRecord entities. +type VirtualMachineRecycleRecordSelect struct { + *VirtualMachineRecycleRecordQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *VirtualMachineRecycleRecordSelect) Aggregate(fns ...AggregateFunc) *VirtualMachineRecycleRecordSelect { + _s.fns = append(_s.fns, fns...) + return _s +} + +// Scan applies the selector query and scans the result into the given value. +func (_s *VirtualMachineRecycleRecordSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*VirtualMachineRecycleRecordQuery, *VirtualMachineRecycleRecordSelect](ctx, _s.VirtualMachineRecycleRecordQuery, _s, _s.inters, v) +} + +func (_s *VirtualMachineRecycleRecordSelect) sqlScan(ctx context.Context, root *VirtualMachineRecycleRecordQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// Modify adds a query modifier for attaching custom logic to queries. +func (_s *VirtualMachineRecycleRecordSelect) Modify(modifiers ...func(s *sql.Selector)) *VirtualMachineRecycleRecordSelect { + _s.modifiers = append(_s.modifiers, modifiers...) + return _s +} diff --git a/backend/db/virtualmachinerecyclerecord_update.go b/backend/db/virtualmachinerecyclerecord_update.go new file mode 100644 index 000000000..5c0cbe59b --- /dev/null +++ b/backend/db/virtualmachinerecyclerecord_update.go @@ -0,0 +1,525 @@ +// Code generated by ent, DO NOT EDIT. + +package db + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/dialect/sql/sqljson" + "entgo.io/ent/schema/field" + "github.com/chaitin/MonkeyCode/backend/consts" + "github.com/chaitin/MonkeyCode/backend/db/predicate" + "github.com/chaitin/MonkeyCode/backend/db/virtualmachinerecyclerecord" + "github.com/google/uuid" +) + +// VirtualMachineRecycleRecordUpdate is the builder for updating VirtualMachineRecycleRecord entities. +type VirtualMachineRecycleRecordUpdate struct { + config + hooks []Hook + mutation *VirtualMachineRecycleRecordMutation + modifiers []func(*sql.UpdateBuilder) +} + +// Where appends a list predicates to the VirtualMachineRecycleRecordUpdate builder. +func (_u *VirtualMachineRecycleRecordUpdate) Where(ps ...predicate.VirtualMachineRecycleRecord) *VirtualMachineRecycleRecordUpdate { + _u.mutation.Where(ps...) + return _u +} + +// SetVirtualmachineID sets the "virtualmachine_id" field. +func (_u *VirtualMachineRecycleRecordUpdate) SetVirtualmachineID(v string) *VirtualMachineRecycleRecordUpdate { + _u.mutation.SetVirtualmachineID(v) + return _u +} + +// SetNillableVirtualmachineID sets the "virtualmachine_id" field if the given value is not nil. +func (_u *VirtualMachineRecycleRecordUpdate) SetNillableVirtualmachineID(v *string) *VirtualMachineRecycleRecordUpdate { + if v != nil { + _u.SetVirtualmachineID(*v) + } + return _u +} + +// SetEnvironmentID sets the "environment_id" field. +func (_u *VirtualMachineRecycleRecordUpdate) SetEnvironmentID(v string) *VirtualMachineRecycleRecordUpdate { + _u.mutation.SetEnvironmentID(v) + return _u +} + +// SetNillableEnvironmentID sets the "environment_id" field if the given value is not nil. +func (_u *VirtualMachineRecycleRecordUpdate) SetNillableEnvironmentID(v *string) *VirtualMachineRecycleRecordUpdate { + if v != nil { + _u.SetEnvironmentID(*v) + } + return _u +} + +// SetHostID sets the "host_id" field. +func (_u *VirtualMachineRecycleRecordUpdate) SetHostID(v string) *VirtualMachineRecycleRecordUpdate { + _u.mutation.SetHostID(v) + return _u +} + +// SetNillableHostID sets the "host_id" field if the given value is not nil. +func (_u *VirtualMachineRecycleRecordUpdate) SetNillableHostID(v *string) *VirtualMachineRecycleRecordUpdate { + if v != nil { + _u.SetHostID(*v) + } + return _u +} + +// SetUserID sets the "user_id" field. +func (_u *VirtualMachineRecycleRecordUpdate) SetUserID(v uuid.UUID) *VirtualMachineRecycleRecordUpdate { + _u.mutation.SetUserID(v) + return _u +} + +// SetNillableUserID sets the "user_id" field if the given value is not nil. +func (_u *VirtualMachineRecycleRecordUpdate) SetNillableUserID(v *uuid.UUID) *VirtualMachineRecycleRecordUpdate { + if v != nil { + _u.SetUserID(*v) + } + return _u +} + +// ClearUserID clears the value of the "user_id" field. +func (_u *VirtualMachineRecycleRecordUpdate) ClearUserID() *VirtualMachineRecycleRecordUpdate { + _u.mutation.ClearUserID() + return _u +} + +// SetTaskIds sets the "task_ids" field. +func (_u *VirtualMachineRecycleRecordUpdate) SetTaskIds(v []uuid.UUID) *VirtualMachineRecycleRecordUpdate { + _u.mutation.SetTaskIds(v) + return _u +} + +// AppendTaskIds appends value to the "task_ids" field. +func (_u *VirtualMachineRecycleRecordUpdate) AppendTaskIds(v []uuid.UUID) *VirtualMachineRecycleRecordUpdate { + _u.mutation.AppendTaskIds(v) + return _u +} + +// SetMethod sets the "method" field. +func (_u *VirtualMachineRecycleRecordUpdate) SetMethod(v consts.VMRecycleMethod) *VirtualMachineRecycleRecordUpdate { + _u.mutation.SetMethod(v) + return _u +} + +// SetNillableMethod sets the "method" field if the given value is not nil. +func (_u *VirtualMachineRecycleRecordUpdate) SetNillableMethod(v *consts.VMRecycleMethod) *VirtualMachineRecycleRecordUpdate { + if v != nil { + _u.SetMethod(*v) + } + return _u +} + +// SetRemoteDeleted sets the "remote_deleted" field. +func (_u *VirtualMachineRecycleRecordUpdate) SetRemoteDeleted(v bool) *VirtualMachineRecycleRecordUpdate { + _u.mutation.SetRemoteDeleted(v) + return _u +} + +// SetNillableRemoteDeleted sets the "remote_deleted" field if the given value is not nil. +func (_u *VirtualMachineRecycleRecordUpdate) SetNillableRemoteDeleted(v *bool) *VirtualMachineRecycleRecordUpdate { + if v != nil { + _u.SetRemoteDeleted(*v) + } + return _u +} + +// SetRecycledAt sets the "recycled_at" field. +func (_u *VirtualMachineRecycleRecordUpdate) SetRecycledAt(v time.Time) *VirtualMachineRecycleRecordUpdate { + _u.mutation.SetRecycledAt(v) + return _u +} + +// SetNillableRecycledAt sets the "recycled_at" field if the given value is not nil. +func (_u *VirtualMachineRecycleRecordUpdate) SetNillableRecycledAt(v *time.Time) *VirtualMachineRecycleRecordUpdate { + if v != nil { + _u.SetRecycledAt(*v) + } + return _u +} + +// SetCreatedAt sets the "created_at" field. +func (_u *VirtualMachineRecycleRecordUpdate) SetCreatedAt(v time.Time) *VirtualMachineRecycleRecordUpdate { + _u.mutation.SetCreatedAt(v) + return _u +} + +// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. +func (_u *VirtualMachineRecycleRecordUpdate) SetNillableCreatedAt(v *time.Time) *VirtualMachineRecycleRecordUpdate { + if v != nil { + _u.SetCreatedAt(*v) + } + return _u +} + +// Mutation returns the VirtualMachineRecycleRecordMutation object of the builder. +func (_u *VirtualMachineRecycleRecordUpdate) Mutation() *VirtualMachineRecycleRecordMutation { + return _u.mutation +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (_u *VirtualMachineRecycleRecordUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *VirtualMachineRecycleRecordUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (_u *VirtualMachineRecycleRecordUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *VirtualMachineRecycleRecordUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +// Modify adds a statement modifier for attaching custom logic to the UPDATE statement. +func (_u *VirtualMachineRecycleRecordUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *VirtualMachineRecycleRecordUpdate { + _u.modifiers = append(_u.modifiers, modifiers...) + return _u +} + +func (_u *VirtualMachineRecycleRecordUpdate) sqlSave(ctx context.Context) (_node int, err error) { + _spec := sqlgraph.NewUpdateSpec(virtualmachinerecyclerecord.Table, virtualmachinerecyclerecord.Columns, sqlgraph.NewFieldSpec(virtualmachinerecyclerecord.FieldID, field.TypeUUID)) + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.VirtualmachineID(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldVirtualmachineID, field.TypeString, value) + } + if value, ok := _u.mutation.EnvironmentID(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldEnvironmentID, field.TypeString, value) + } + if value, ok := _u.mutation.HostID(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldHostID, field.TypeString, value) + } + if value, ok := _u.mutation.UserID(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldUserID, field.TypeUUID, value) + } + if _u.mutation.UserIDCleared() { + _spec.ClearField(virtualmachinerecyclerecord.FieldUserID, field.TypeUUID) + } + if value, ok := _u.mutation.TaskIds(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldTaskIds, field.TypeJSON, value) + } + if value, ok := _u.mutation.AppendedTaskIds(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, virtualmachinerecyclerecord.FieldTaskIds, value) + }) + } + if value, ok := _u.mutation.Method(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldMethod, field.TypeString, value) + } + if value, ok := _u.mutation.RemoteDeleted(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldRemoteDeleted, field.TypeBool, value) + } + if value, ok := _u.mutation.RecycledAt(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldRecycledAt, field.TypeTime, value) + } + if value, ok := _u.mutation.CreatedAt(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldCreatedAt, field.TypeTime, value) + } + _spec.AddModifiers(_u.modifiers...) + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{virtualmachinerecyclerecord.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + _u.mutation.done = true + return _node, nil +} + +// VirtualMachineRecycleRecordUpdateOne is the builder for updating a single VirtualMachineRecycleRecord entity. +type VirtualMachineRecycleRecordUpdateOne struct { + config + fields []string + hooks []Hook + mutation *VirtualMachineRecycleRecordMutation + modifiers []func(*sql.UpdateBuilder) +} + +// SetVirtualmachineID sets the "virtualmachine_id" field. +func (_u *VirtualMachineRecycleRecordUpdateOne) SetVirtualmachineID(v string) *VirtualMachineRecycleRecordUpdateOne { + _u.mutation.SetVirtualmachineID(v) + return _u +} + +// SetNillableVirtualmachineID sets the "virtualmachine_id" field if the given value is not nil. +func (_u *VirtualMachineRecycleRecordUpdateOne) SetNillableVirtualmachineID(v *string) *VirtualMachineRecycleRecordUpdateOne { + if v != nil { + _u.SetVirtualmachineID(*v) + } + return _u +} + +// SetEnvironmentID sets the "environment_id" field. +func (_u *VirtualMachineRecycleRecordUpdateOne) SetEnvironmentID(v string) *VirtualMachineRecycleRecordUpdateOne { + _u.mutation.SetEnvironmentID(v) + return _u +} + +// SetNillableEnvironmentID sets the "environment_id" field if the given value is not nil. +func (_u *VirtualMachineRecycleRecordUpdateOne) SetNillableEnvironmentID(v *string) *VirtualMachineRecycleRecordUpdateOne { + if v != nil { + _u.SetEnvironmentID(*v) + } + return _u +} + +// SetHostID sets the "host_id" field. +func (_u *VirtualMachineRecycleRecordUpdateOne) SetHostID(v string) *VirtualMachineRecycleRecordUpdateOne { + _u.mutation.SetHostID(v) + return _u +} + +// SetNillableHostID sets the "host_id" field if the given value is not nil. +func (_u *VirtualMachineRecycleRecordUpdateOne) SetNillableHostID(v *string) *VirtualMachineRecycleRecordUpdateOne { + if v != nil { + _u.SetHostID(*v) + } + return _u +} + +// SetUserID sets the "user_id" field. +func (_u *VirtualMachineRecycleRecordUpdateOne) SetUserID(v uuid.UUID) *VirtualMachineRecycleRecordUpdateOne { + _u.mutation.SetUserID(v) + return _u +} + +// SetNillableUserID sets the "user_id" field if the given value is not nil. +func (_u *VirtualMachineRecycleRecordUpdateOne) SetNillableUserID(v *uuid.UUID) *VirtualMachineRecycleRecordUpdateOne { + if v != nil { + _u.SetUserID(*v) + } + return _u +} + +// ClearUserID clears the value of the "user_id" field. +func (_u *VirtualMachineRecycleRecordUpdateOne) ClearUserID() *VirtualMachineRecycleRecordUpdateOne { + _u.mutation.ClearUserID() + return _u +} + +// SetTaskIds sets the "task_ids" field. +func (_u *VirtualMachineRecycleRecordUpdateOne) SetTaskIds(v []uuid.UUID) *VirtualMachineRecycleRecordUpdateOne { + _u.mutation.SetTaskIds(v) + return _u +} + +// AppendTaskIds appends value to the "task_ids" field. +func (_u *VirtualMachineRecycleRecordUpdateOne) AppendTaskIds(v []uuid.UUID) *VirtualMachineRecycleRecordUpdateOne { + _u.mutation.AppendTaskIds(v) + return _u +} + +// SetMethod sets the "method" field. +func (_u *VirtualMachineRecycleRecordUpdateOne) SetMethod(v consts.VMRecycleMethod) *VirtualMachineRecycleRecordUpdateOne { + _u.mutation.SetMethod(v) + return _u +} + +// SetNillableMethod sets the "method" field if the given value is not nil. +func (_u *VirtualMachineRecycleRecordUpdateOne) SetNillableMethod(v *consts.VMRecycleMethod) *VirtualMachineRecycleRecordUpdateOne { + if v != nil { + _u.SetMethod(*v) + } + return _u +} + +// SetRemoteDeleted sets the "remote_deleted" field. +func (_u *VirtualMachineRecycleRecordUpdateOne) SetRemoteDeleted(v bool) *VirtualMachineRecycleRecordUpdateOne { + _u.mutation.SetRemoteDeleted(v) + return _u +} + +// SetNillableRemoteDeleted sets the "remote_deleted" field if the given value is not nil. +func (_u *VirtualMachineRecycleRecordUpdateOne) SetNillableRemoteDeleted(v *bool) *VirtualMachineRecycleRecordUpdateOne { + if v != nil { + _u.SetRemoteDeleted(*v) + } + return _u +} + +// SetRecycledAt sets the "recycled_at" field. +func (_u *VirtualMachineRecycleRecordUpdateOne) SetRecycledAt(v time.Time) *VirtualMachineRecycleRecordUpdateOne { + _u.mutation.SetRecycledAt(v) + return _u +} + +// SetNillableRecycledAt sets the "recycled_at" field if the given value is not nil. +func (_u *VirtualMachineRecycleRecordUpdateOne) SetNillableRecycledAt(v *time.Time) *VirtualMachineRecycleRecordUpdateOne { + if v != nil { + _u.SetRecycledAt(*v) + } + return _u +} + +// SetCreatedAt sets the "created_at" field. +func (_u *VirtualMachineRecycleRecordUpdateOne) SetCreatedAt(v time.Time) *VirtualMachineRecycleRecordUpdateOne { + _u.mutation.SetCreatedAt(v) + return _u +} + +// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. +func (_u *VirtualMachineRecycleRecordUpdateOne) SetNillableCreatedAt(v *time.Time) *VirtualMachineRecycleRecordUpdateOne { + if v != nil { + _u.SetCreatedAt(*v) + } + return _u +} + +// Mutation returns the VirtualMachineRecycleRecordMutation object of the builder. +func (_u *VirtualMachineRecycleRecordUpdateOne) Mutation() *VirtualMachineRecycleRecordMutation { + return _u.mutation +} + +// Where appends a list predicates to the VirtualMachineRecycleRecordUpdate builder. +func (_u *VirtualMachineRecycleRecordUpdateOne) Where(ps ...predicate.VirtualMachineRecycleRecord) *VirtualMachineRecycleRecordUpdateOne { + _u.mutation.Where(ps...) + return _u +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (_u *VirtualMachineRecycleRecordUpdateOne) Select(field string, fields ...string) *VirtualMachineRecycleRecordUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u +} + +// Save executes the query and returns the updated VirtualMachineRecycleRecord entity. +func (_u *VirtualMachineRecycleRecordUpdateOne) Save(ctx context.Context) (*VirtualMachineRecycleRecord, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *VirtualMachineRecycleRecordUpdateOne) SaveX(ctx context.Context) *VirtualMachineRecycleRecord { + node, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (_u *VirtualMachineRecycleRecordUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *VirtualMachineRecycleRecordUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +// Modify adds a statement modifier for attaching custom logic to the UPDATE statement. +func (_u *VirtualMachineRecycleRecordUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) *VirtualMachineRecycleRecordUpdateOne { + _u.modifiers = append(_u.modifiers, modifiers...) + return _u +} + +func (_u *VirtualMachineRecycleRecordUpdateOne) sqlSave(ctx context.Context) (_node *VirtualMachineRecycleRecord, err error) { + _spec := sqlgraph.NewUpdateSpec(virtualmachinerecyclerecord.Table, virtualmachinerecyclerecord.Columns, sqlgraph.NewFieldSpec(virtualmachinerecyclerecord.FieldID, field.TypeUUID)) + id, ok := _u.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`db: missing "VirtualMachineRecycleRecord.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := _u.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, virtualmachinerecyclerecord.FieldID) + for _, f := range fields { + if !virtualmachinerecyclerecord.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("db: invalid field %q for query", f)} + } + if f != virtualmachinerecyclerecord.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.VirtualmachineID(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldVirtualmachineID, field.TypeString, value) + } + if value, ok := _u.mutation.EnvironmentID(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldEnvironmentID, field.TypeString, value) + } + if value, ok := _u.mutation.HostID(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldHostID, field.TypeString, value) + } + if value, ok := _u.mutation.UserID(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldUserID, field.TypeUUID, value) + } + if _u.mutation.UserIDCleared() { + _spec.ClearField(virtualmachinerecyclerecord.FieldUserID, field.TypeUUID) + } + if value, ok := _u.mutation.TaskIds(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldTaskIds, field.TypeJSON, value) + } + if value, ok := _u.mutation.AppendedTaskIds(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, virtualmachinerecyclerecord.FieldTaskIds, value) + }) + } + if value, ok := _u.mutation.Method(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldMethod, field.TypeString, value) + } + if value, ok := _u.mutation.RemoteDeleted(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldRemoteDeleted, field.TypeBool, value) + } + if value, ok := _u.mutation.RecycledAt(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldRecycledAt, field.TypeTime, value) + } + if value, ok := _u.mutation.CreatedAt(); ok { + _spec.SetField(virtualmachinerecyclerecord.FieldCreatedAt, field.TypeTime, value) + } + _spec.AddModifiers(_u.modifiers...) + _node = &VirtualMachineRecycleRecord{config: _u.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{virtualmachinerecyclerecord.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + _u.mutation.done = true + return _node, nil +} diff --git a/backend/domain/host.go b/backend/domain/host.go index 8438e5f9d..276a319df 100644 --- a/backend/domain/host.go +++ b/backend/domain/host.go @@ -90,7 +90,8 @@ type VmIdleInfo struct { TaskID string `json:"task_id,omitempty"` // 关联的任务 ID,用于通知 Name string `json:"name,omitempty"` // 任务名称,用于通知内容 // RecycleDeleteExhausted 表示远端删除已重试耗尽,后续消费只补写回收状态。 - RecycleDeleteExhausted bool `json:"recycle_delete_exhausted,omitempty"` + RecycleDeleteExhausted bool `json:"recycle_delete_exhausted,omitempty"` + RecycleMethod consts.VMRecycleMethod `json:"recycle_method,omitempty"` // RecycleAt 是本次 RecordActivity 算出的预计回收时间。每次用户活动都会延长这个值, // consumer 把它编进 RefID,让每个回收窗口都能产生不同的 dedup key(否则 // dispatcher 会按 (subID, eventType, RefID) 把同一 task 的后续推送全部静默)。 diff --git a/backend/ent/schema/virtualmachinerecyclerecord.go b/backend/ent/schema/virtualmachinerecyclerecord.go new file mode 100644 index 000000000..c28065ee2 --- /dev/null +++ b/backend/ent/schema/virtualmachinerecyclerecord.go @@ -0,0 +1,46 @@ +package schema + +import ( + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/entsql" + "entgo.io/ent/schema" + "entgo.io/ent/schema/field" + "entgo.io/ent/schema/index" + "github.com/google/uuid" + + "github.com/chaitin/MonkeyCode/backend/consts" +) + +type VirtualMachineRecycleRecord struct { + ent.Schema +} + +func (VirtualMachineRecycleRecord) Annotations() []schema.Annotation { + return []schema.Annotation{ + entsql.Table("virtualmachine_recycle_records"), + } +} + +func (VirtualMachineRecycleRecord) Fields() []ent.Field { + return []ent.Field{ + field.UUID("id", uuid.UUID{}).Unique(), + field.String("virtualmachine_id").Unique(), + field.String("environment_id"), + field.String("host_id"), + field.UUID("user_id", uuid.UUID{}).Optional().Nillable(), + field.JSON("task_ids", []uuid.UUID{}), + field.String("method").GoType(consts.VMRecycleMethod("")), + field.Bool("remote_deleted").Default(false), + field.Time("recycled_at"), + field.Time("created_at").Default(time.Now), + } +} + +func (VirtualMachineRecycleRecord) Indexes() []ent.Index { + return []ent.Index{ + index.Fields("method", "recycled_at"), + index.Fields("user_id", "recycled_at"), + } +} diff --git a/backend/migration/000025_create_virtualmachine_recycle_records.down.sql b/backend/migration/000025_create_virtualmachine_recycle_records.down.sql new file mode 100644 index 000000000..4113e5b33 --- /dev/null +++ b/backend/migration/000025_create_virtualmachine_recycle_records.down.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS virtualmachine_recycle_records; diff --git a/backend/migration/000025_create_virtualmachine_recycle_records.up.sql b/backend/migration/000025_create_virtualmachine_recycle_records.up.sql new file mode 100644 index 000000000..22457ac56 --- /dev/null +++ b/backend/migration/000025_create_virtualmachine_recycle_records.up.sql @@ -0,0 +1,18 @@ +CREATE TABLE IF NOT EXISTS virtualmachine_recycle_records ( + id uuid PRIMARY KEY, + virtualmachine_id varchar NOT NULL UNIQUE, + environment_id varchar NOT NULL DEFAULT '', + host_id varchar NOT NULL DEFAULT '', + user_id uuid, + task_ids jsonb NOT NULL DEFAULT '[]'::jsonb, + method varchar NOT NULL, + remote_deleted boolean NOT NULL DEFAULT false, + recycled_at timestamptz NOT NULL, + created_at timestamptz NOT NULL DEFAULT now() +); + +CREATE INDEX IF NOT EXISTS idx_virtualmachine_recycle_records_method_recycled_at + ON virtualmachine_recycle_records (method, recycled_at); + +CREATE INDEX IF NOT EXISTS idx_virtualmachine_recycle_records_user_recycled_at + ON virtualmachine_recycle_records (user_id, recycled_at); diff --git a/backend/pkg/delayqueue/delayqueue.go b/backend/pkg/delayqueue/delayqueue.go index c3f010fc5..44250d0ea 100644 --- a/backend/pkg/delayqueue/delayqueue.go +++ b/backend/pkg/delayqueue/delayqueue.go @@ -50,6 +50,8 @@ const ( // ErrRetryAfterMaxAttempts 让已耗尽普通尝试次数的任务继续保留并重试。 var ErrRetryAfterMaxAttempts = errors.New("retry delay queue job after max attempts") +var ErrJobRescheduled = errors.New("delay queue job rescheduled") + // NewRedisDelayQueue 创建延迟队列(泛型) func NewRedisDelayQueue[T any](rdb *redis.Client, logger *slog.Logger, opts ...Option[T]) *RedisDelayQueue[T] { q := &RedisDelayQueue[T]{ @@ -239,6 +241,10 @@ func (q *RedisDelayQueue[T]) pollOnce(ctx context.Context, queue string, handler continue } if err := handler(ctx, job); err != nil { + if errors.Is(err, ErrJobRescheduled) { + q.logger.Debug("delayqueue job rescheduled", "queue", queue, "id", id) + continue + } q.logger.Warn("handle job failed, will requeue", "queue", queue, "id", id, "attempts", job.Attempts+1, "err", err) job.Attempts++ retryAfterMaxAttempts := errors.Is(err, ErrRetryAfterMaxAttempts) diff --git a/backend/pkg/delayqueue/delayqueue_test.go b/backend/pkg/delayqueue/delayqueue_test.go index 494c2bf9c..9cc32411d 100644 --- a/backend/pkg/delayqueue/delayqueue_test.go +++ b/backend/pkg/delayqueue/delayqueue_test.go @@ -142,3 +142,31 @@ func TestPollOncePreservesJobForRetryAfterMaxAttempts(t *testing.T) { t.Fatalf("job preserved = %v, err = %v, want removed", ok, err) } } + +func TestPollOncePreservesRefreshedJob(t *testing.T) { + ctx := context.Background() + srv := miniredis.RunT(t) + rdb := redis.NewClient(&redis.Options{Addr: srv.Addr()}) + t.Cleanup(func() { _ = rdb.Close() }) + queue := NewRedisDelayQueue[string](rdb, slog.Default()) + if _, err := queue.Enqueue(ctx, "recycle", "old", time.Now(), "vm-1"); err != nil { + t.Fatal(err) + } + refreshedAt := time.Now().Add(time.Hour).Truncate(time.Millisecond) + + if err := queue.pollOnce(ctx, "recycle", func(context.Context, *Job[string]) error { + if _, err := queue.Enqueue(ctx, "recycle", "refreshed", refreshedAt, "vm-1"); err != nil { + return err + } + return ErrJobRescheduled + }); err != nil { + t.Fatal(err) + } + job, runAt, ok, err := queue.GetJobInfo(ctx, "recycle", "vm-1") + if err != nil || !ok { + t.Fatalf("refreshed job ok = %v, err = %v", ok, err) + } + if job.Payload != "refreshed" || !runAt.Equal(refreshedAt) || job.Attempts != 0 { + t.Fatalf("job = %+v, run at = %v", job, runAt) + } +} diff --git a/backend/pkg/lifecycle/types.go b/backend/pkg/lifecycle/types.go index 62f96a43f..a6ebabeac 100644 --- a/backend/pkg/lifecycle/types.go +++ b/backend/pkg/lifecycle/types.go @@ -5,6 +5,8 @@ import ( "context" "github.com/google/uuid" + + "github.com/chaitin/MonkeyCode/backend/consts" ) // State 状态类型约束(支持 string 及其派生类型) @@ -48,8 +50,9 @@ const ( // VMMetadata 虚拟机元数据 type VMMetadata struct { - VMID string `json:"vm_id"` - TaskID *uuid.UUID `json:"task_id"` - UserID uuid.UUID `json:"user_id"` - Region string `json:"region,omitempty"` + VMID string `json:"vm_id"` + TaskID *uuid.UUID `json:"task_id"` + UserID uuid.UUID `json:"user_id"` + Region string `json:"region,omitempty"` + RecycleMethod consts.VMRecycleMethod `json:"recycle_method,omitempty"` } diff --git a/backend/pkg/lifecycle/vmrecyclehook.go b/backend/pkg/lifecycle/vmrecyclehook.go index 01dcc537a..d7d3e3dfc 100644 --- a/backend/pkg/lifecycle/vmrecyclehook.go +++ b/backend/pkg/lifecycle/vmrecyclehook.go @@ -9,6 +9,7 @@ import ( "github.com/samber/do" + "github.com/chaitin/MonkeyCode/backend/consts" "github.com/chaitin/MonkeyCode/backend/domain" "github.com/chaitin/MonkeyCode/backend/pkg/delayqueue" "github.com/chaitin/MonkeyCode/backend/pkg/vmrecycle" @@ -36,12 +37,16 @@ func (h *VMRecycleHook) OnStateChange(ctx context.Context, vmID string, _, to VM if to != VMStateRecycled { return nil } + method := metadata.RecycleMethod + if method == "" { + method = consts.VMRecycleMethodLifecycle + } - if _, err := h.recycler.Recycle(ctx, vmID); err == nil { + if _, err := h.recycler.Recycle(ctx, vmID, method); err == nil { return nil } else { h.logger.WarnContext(ctx, "vm recycle failed, enqueueing retry", "vm_id", vmID, "error", err) - payload := &domain.VmIdleInfo{UID: metadata.UserID, VmID: vmID} + payload := &domain.VmIdleInfo{UID: metadata.UserID, VmID: vmID, RecycleMethod: method} if metadata.TaskID != nil { payload.TaskID = metadata.TaskID.String() } diff --git a/backend/pkg/lifecycle/vmrecyclehook_test.go b/backend/pkg/lifecycle/vmrecyclehook_test.go index fe407e948..fb97872bd 100644 --- a/backend/pkg/lifecycle/vmrecyclehook_test.go +++ b/backend/pkg/lifecycle/vmrecyclehook_test.go @@ -11,6 +11,7 @@ import ( "github.com/google/uuid" "github.com/redis/go-redis/v9" + "github.com/chaitin/MonkeyCode/backend/consts" "github.com/chaitin/MonkeyCode/backend/pkg/delayqueue" "github.com/chaitin/MonkeyCode/backend/pkg/vmrecycle" ) @@ -85,10 +86,16 @@ type lifecycleRecyclerStub struct { err error calls int vmID string + method consts.VMRecycleMethod } -func (s *lifecycleRecyclerStub) Recycle(_ context.Context, vmID string) (vmrecycle.Result, error) { +func (s *lifecycleRecyclerStub) Recycle(_ context.Context, vmID string, method consts.VMRecycleMethod) (vmrecycle.Result, error) { s.calls++ s.vmID = vmID + s.method = method return s.result, s.err } + +func (s *lifecycleRecyclerStub) ForceRecycle(context.Context, string, consts.VMRecycleMethod) (vmrecycle.Result, error) { + return vmrecycle.Result{}, errors.New("not implemented") +} diff --git a/backend/pkg/register.go b/backend/pkg/register.go index b66360349..b4f471488 100644 --- a/backend/pkg/register.go +++ b/backend/pkg/register.go @@ -196,6 +196,7 @@ func RegisterInfra(i *do.Injector, w ...*web.Web) error { return delayqueue.NewVMExpireQueue(r, l), nil }) + do.Provide(i, vmrecycle.NewRecorder) do.Provide(i, vmrecycle.NewRecycler) do.Provide(i, vmrecycle.NewAnalyzer) do.Provide(i, vmrecycle.NewDeadlineRepairer) diff --git a/backend/pkg/vmrecycle/deadline_repair.go b/backend/pkg/vmrecycle/deadline_repair.go index be684ef16..aa93e7ce1 100644 --- a/backend/pkg/vmrecycle/deadline_repair.go +++ b/backend/pkg/vmrecycle/deadline_repair.go @@ -72,11 +72,12 @@ func (r *deadlineRepairer) Repair(ctx context.Context, vmID string) (DeadlineRep recycleAt := r.now().Add(time.Duration(policy.EffectiveRecycleSeconds) * time.Second) payload := &domain.VmIdleInfo{ - UID: vm.UserID, - VmID: vm.ID, - HostID: vm.HostID, - EnvID: vm.EnvironmentID, - RecycleAt: recycleAt, + UID: vm.UserID, + VmID: vm.ID, + HostID: vm.HostID, + EnvID: vm.EnvironmentID, + RecycleAt: recycleAt, + RecycleMethod: consts.VMRecycleMethodIdle, } _, added, err := r.queue.EnqueueIfMissing(ctx, RecycleQueueKey, payload, recycleAt, vm.ID) if err != nil { diff --git a/backend/pkg/vmrecycle/record.go b/backend/pkg/vmrecycle/record.go new file mode 100644 index 000000000..5b27701d7 --- /dev/null +++ b/backend/pkg/vmrecycle/record.go @@ -0,0 +1,57 @@ +package vmrecycle + +import ( + "context" + "time" + + "github.com/google/uuid" + "github.com/samber/do" + + "github.com/chaitin/MonkeyCode/backend/consts" + "github.com/chaitin/MonkeyCode/backend/db" + "github.com/chaitin/MonkeyCode/backend/db/virtualmachinerecyclerecord" +) + +type Record struct { + VMID string + EnvironmentID string + HostID string + UserID uuid.UUID + TaskIDs []uuid.UUID + Method consts.VMRecycleMethod + RemoteDeleted bool + RecycledAt time.Time +} + +type Recorder interface { + Create(ctx context.Context, record Record) error +} + +type recorder struct { + db *db.Client +} + +func NewRecorder(i *do.Injector) (Recorder, error) { + return &recorder{db: do.MustInvoke[*db.Client](i)}, nil +} + +func (r *recorder) Create(ctx context.Context, record Record) error { + create := r.db.VirtualMachineRecycleRecord.Create(). + SetID(uuid.New()). + SetVirtualmachineID(record.VMID). + SetEnvironmentID(record.EnvironmentID). + SetHostID(record.HostID). + SetTaskIds(record.TaskIDs). + SetMethod(record.Method). + SetRemoteDeleted(record.RemoteDeleted). + SetRecycledAt(record.RecycledAt) + if record.UserID != uuid.Nil { + create.SetUserID(record.UserID) + } + return create. + OnConflictColumns(virtualmachinerecyclerecord.FieldVirtualmachineID). + Ignore(). + Exec(ctx) +} + +var _ Recorder = (*recorder)(nil) diff --git a/backend/pkg/vmrecycle/vmrecycle.go b/backend/pkg/vmrecycle/vmrecycle.go index a9d80adee..c507377bc 100644 --- a/backend/pkg/vmrecycle/vmrecycle.go +++ b/backend/pkg/vmrecycle/vmrecycle.go @@ -49,12 +49,8 @@ type Result struct { } type Recycler interface { - Recycle(ctx context.Context, vmID string) (Result, error) -} - -type ForceRecycler interface { - Recycler - ForceRecycle(ctx context.Context, vmID string) (Result, error) + Recycle(ctx context.Context, vmID string, method consts.VMRecycleMethod) (Result, error) + ForceRecycle(ctx context.Context, vmID string, method consts.VMRecycleMethod) (Result, error) } type removableQueue interface { @@ -76,6 +72,7 @@ type recycler struct { notifyQueue notifyQueue recycleQueue removableQueue expireQueue removableQueue + recorder Recorder now func() time.Time } @@ -90,20 +87,24 @@ func NewRecycler(i *do.Injector) (Recycler, error) { notifyQueue: do.MustInvoke[*delayqueue.VMNotifyQueue](i), recycleQueue: do.MustInvoke[*delayqueue.VMRecycleQueue](i), expireQueue: do.MustInvoke[*delayqueue.VMExpireQueue](i), + recorder: do.MustInvoke[Recorder](i), now: time.Now, }, nil } -func (r *recycler) Recycle(ctx context.Context, vmID string) (Result, error) { - return r.recycle(ctx, vmID, false) +func (r *recycler) Recycle(ctx context.Context, vmID string, method consts.VMRecycleMethod) (Result, error) { + return r.recycle(ctx, vmID, method, false) } -func (r *recycler) ForceRecycle(ctx context.Context, vmID string) (Result, error) { - return r.recycle(ctx, vmID, true) +func (r *recycler) ForceRecycle(ctx context.Context, vmID string, method consts.VMRecycleMethod) (Result, error) { + return r.recycle(ctx, vmID, method, true) } -func (r *recycler) recycle(ctx context.Context, vmID string, ignoreRemoteDeleteFailure bool) (Result, error) { +func (r *recycler) recycle(ctx context.Context, vmID string, method consts.VMRecycleMethod, ignoreRemoteDeleteFailure bool) (Result, error) { result := Result{VMID: vmID} + if method == "" { + method = consts.VMRecycleMethodLifecycle + } token, err := r.acquire(ctx, vmID) if err != nil { return result, err @@ -120,6 +121,8 @@ func (r *recycler) recycle(ctx context.Context, vmID string, ignoreRemoteDeleteF return result, fmt.Errorf("get vm %s: %w", vmID, err) } result.TaskIDs = taskIDs(vm) + remoteDeleted := vm.IsRecycled + recycledAt := r.now() if vm.IsRecycled { result.Status = StatusAlreadyRecycled @@ -129,7 +132,8 @@ func (r *recycler) recycle(ctx context.Context, vmID string, ignoreRemoteDeleteF HostID: vm.HostID, ID: vm.EnvironmentID, }) - if deleteErr != nil && !taskflow.IsVirtualMachineNotFound(deleteErr) { + remoteDeleted = deleteErr == nil || taskflow.IsVirtualMachineNotFound(deleteErr) + if !remoteDeleted { if !ignoreRemoteDeleteFailure { return result, fmt.Errorf("%w: delete vm %s: %w", ErrRemoteDelete, vmID, deleteErr) } @@ -143,6 +147,20 @@ func (r *recycler) recycle(ctx context.Context, vmID string, ignoreRemoteDeleteF } result.Status = StatusRecycled } + if r.recorder != nil { + if err := r.recorder.Create(ctx, Record{ + VMID: vm.ID, + EnvironmentID: vm.EnvironmentID, + HostID: vm.HostID, + UserID: vm.UserID, + TaskIDs: result.TaskIDs, + Method: method, + RemoteDeleted: remoteDeleted, + RecycledAt: recycledAt, + }); err != nil { + return result, fmt.Errorf("record vm %s recycle: %w", vmID, err) + } + } if err := r.cleanup(ctx, vm); err != nil { return result, err diff --git a/backend/pkg/vmrecycle/vmrecycle_test.go b/backend/pkg/vmrecycle/vmrecycle_test.go index 1c87103fe..2e2418c43 100644 --- a/backend/pkg/vmrecycle/vmrecycle_test.go +++ b/backend/pkg/vmrecycle/vmrecycle_test.go @@ -37,6 +37,7 @@ func TestRecyclerRecyclesVMAndCleansLocalState(t *testing.T) { hostRepo := &recycleHostRepoStub{vm: vm} taskRepo := &recycleTaskRepoStub{} vmClient := &recycleVMStub{} + recorder := &recycleRecorderStub{} logger := slog.New(slog.NewTextHandler(io.Discard, nil)) sleepQueue := delayqueue.NewVMSleepQueue(rdb, logger) notifyQueue := delayqueue.NewVMNotifyQueue(rdb, logger) @@ -52,6 +53,7 @@ func TestRecyclerRecyclesVMAndCleansLocalState(t *testing.T) { notifyQueue: notifyQueue, recycleQueue: recycleQueue, expireQueue: expireQueue, + recorder: recorder, now: func() time.Time { return time.Date(2026, 7, 13, 12, 0, 0, 0, time.UTC) }, } payload := &domain.VmIdleInfo{VmID: vm.ID} @@ -80,7 +82,7 @@ func TestRecyclerRecyclesVMAndCleansLocalState(t *testing.T) { } } - result, err := r.Recycle(ctx, vm.ID) + result, err := r.Recycle(ctx, vm.ID, consts.VMRecycleMethodIdle) if err != nil { t.Fatal(err) } @@ -93,6 +95,16 @@ func TestRecyclerRecyclesVMAndCleansLocalState(t *testing.T) { if hostRepo.updateCalls != 1 || !vm.IsRecycled { t.Fatalf("update calls = %d, recycled = %v", hostRepo.updateCalls, vm.IsRecycled) } + if len(recorder.records) != 1 { + t.Fatalf("records = %d, want 1", len(recorder.records)) + } + record := recorder.records[0] + if record.VMID != vm.ID || record.Method != consts.VMRecycleMethodIdle || !record.RemoteDeleted || !record.RecycledAt.Equal(r.now()) { + t.Fatalf("record = %+v", record) + } + if len(record.TaskIDs) != 2 { + t.Fatalf("record task ids = %v", record.TaskIDs) + } if len(taskRepo.updated) != 1 || taskRepo.updated[0] != processingTaskID { t.Fatalf("updated tasks = %v, want [%s]", taskRepo.updated, processingTaskID) } @@ -116,7 +128,7 @@ func TestRecyclerAlreadyRecycledSkipsRemoteDeleteAndRepairsCleanup(t *testing.T) vm := &db.VirtualMachine{ID: "vm-recycled", IsRecycled: true, Edges: db.VirtualMachineEdges{Tasks: []*db.Task{{ID: uuid.New(), Status: consts.TaskStatusProcessing}}}} r, _, taskRepo, vmClient := newStubRecycler(t, vm) - result, err := r.Recycle(context.Background(), vm.ID) + result, err := r.Recycle(context.Background(), vm.ID, consts.VMRecycleMethodIdle) if err != nil { t.Fatal(err) } @@ -138,7 +150,7 @@ func TestRecyclerRemoteFailureDoesNotMarkOrClean(t *testing.T) { vmClient.err = wantErr queues := r.sleepQueue.(*recycleQueueStub) - result, err := r.Recycle(context.Background(), vm.ID) + result, err := r.Recycle(context.Background(), vm.ID, consts.VMRecycleMethodIdle) if !errors.Is(err, wantErr) { t.Fatalf("error = %v, want %v", err, wantErr) } @@ -155,7 +167,7 @@ func TestRecyclerTreatsMissingRemoteEnvironmentAsDeleted(t *testing.T) { r, hostRepo, taskRepo, vmClient := newStubRecycler(t, vm) vmClient.err = errors.New("recv err failed to stop environment: environment not found: env-1") - result, err := r.Recycle(context.Background(), vm.ID) + result, err := r.Recycle(context.Background(), vm.ID, consts.VMRecycleMethodIdle) if err != nil { t.Fatal(err) } @@ -181,14 +193,7 @@ func TestForceRecyclerContinuesAfterOpaqueRemoteDeleteFailure(t *testing.T) { } r, hostRepo, taskRepo, vmClient := newStubRecycler(t, vm) vmClient.err = errors.New(`HTTP 500: {"code":500,"message":"服务器错误 [trace_id: test]"}`) - forceRecycler, ok := any(r).(interface { - ForceRecycle(context.Context, string) (Result, error) - }) - if !ok { - t.Fatal("recycler must support force recycle") - } - - result, err := forceRecycler.ForceRecycle(context.Background(), vm.ID) + result, err := r.ForceRecycle(context.Background(), vm.ID, consts.VMRecycleMethodForce) if err != nil { t.Fatal(err) } @@ -209,7 +214,7 @@ func TestRecyclerRetriesCleanupWithoutDeletingRemoteAgain(t *testing.T) { sleepQueue := r.sleepQueue.(*recycleQueueStub) sleepQueue.err = errors.New("redis unavailable") - result, err := r.Recycle(context.Background(), vm.ID) + result, err := r.Recycle(context.Background(), vm.ID, consts.VMRecycleMethodIdle) if err == nil || result.Status != StatusRecycled { t.Fatalf("first result = %+v, error = %v", result, err) } @@ -221,7 +226,7 @@ func TestRecyclerRetriesCleanupWithoutDeletingRemoteAgain(t *testing.T) { } sleepQueue.err = nil - result, err = r.Recycle(context.Background(), vm.ID) + result, err = r.Recycle(context.Background(), vm.ID, consts.VMRecycleMethodIdle) if err != nil || result.Status != StatusAlreadyRecycled { t.Fatalf("retry result = %+v, error = %v", result, err) } @@ -240,7 +245,7 @@ func TestRecyclerReturnsInProgressWhenLockExists(t *testing.T) { t.Fatal(err) } - _, err := r.Recycle(context.Background(), vm.ID) + _, err := r.Recycle(context.Background(), vm.ID, consts.VMRecycleMethodIdle) if !errors.Is(err, ErrInProgress) { t.Fatalf("error = %v, want ErrInProgress", err) } @@ -253,7 +258,7 @@ func TestRecyclerReturnsNotFoundResult(t *testing.T) { r, _, _, _ := newStubRecycler(t, nil) r.hostRepo.(*recycleHostRepoStub).err = &db.NotFoundError{} - result, err := r.Recycle(context.Background(), "missing-vm") + result, err := r.Recycle(context.Background(), "missing-vm", consts.VMRecycleMethodIdle) if err != nil { t.Fatal(err) } @@ -332,6 +337,16 @@ type recycleTaskRepoStub struct { err error } +type recycleRecorderStub struct { + records []Record + err error +} + +func (s *recycleRecorderStub) Create(_ context.Context, record Record) error { + s.records = append(s.records, record) + return s.err +} + func (s *recycleTaskRepoStub) Update(_ context.Context, _ *domain.User, id uuid.UUID, _ func(*db.TaskUpdateOne) error) error { s.updated = append(s.updated, id) return s.err From ac931852e145d6ed1e7d7dbccaa619606c0f46aa Mon Sep 17 00:00:00 2001 From: yokowu <18836617@qq.com> Date: Wed, 5 Aug 2026 14:20:39 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E8=A1=A5=E5=85=85=E8=99=9A=E6=8B=9F?= =?UTF-8?q?=E6=9C=BA=E5=9B=9E=E6=94=B6=E6=96=B9=E5=BC=8F=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/consts/host.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/backend/consts/host.go b/backend/consts/host.go index e4d265401..a5f6c31f2 100644 --- a/backend/consts/host.go +++ b/backend/consts/host.go @@ -14,13 +14,13 @@ const ( type VMRecycleMethod string const ( - VMRecycleMethodIdle VMRecycleMethod = "idle" - VMRecycleMethodTaskStop VMRecycleMethod = "task_stop" - VMRecycleMethodTaskDelete VMRecycleMethod = "task_delete" - VMRecycleMethodExpired VMRecycleMethod = "expired" - VMRecycleMethodManualDelete VMRecycleMethod = "manual_delete" - VMRecycleMethodForce VMRecycleMethod = "force" - VMRecycleMethodLifecycle VMRecycleMethod = "lifecycle" + VMRecycleMethodIdle VMRecycleMethod = "idle" // 空闲超时回收 + VMRecycleMethodTaskStop VMRecycleMethod = "task_stop" // 停止任务回收 + VMRecycleMethodTaskDelete VMRecycleMethod = "task_delete" // 删除任务回收 + VMRecycleMethodExpired VMRecycleMethod = "expired" // 虚拟机到期回收 + VMRecycleMethodManualDelete VMRecycleMethod = "manual_delete" // 用户手动删除 + VMRecycleMethodForce VMRecycleMethod = "force" // 强制回收 + VMRecycleMethodLifecycle VMRecycleMethod = "lifecycle" // 生命周期状态回收 ) type HostStatus string