func txnFindManyAndDelete()

in server/datasource/etcd/kv/kv_dao.go [380:449]


func txnFindManyAndDelete(ctx context.Context, kvIDs []string, project, domain string) ([]*model.KVDoc, int64, error) {
	var docs []*model.KVDoc
	var opOptions []etcdadpt.OpOptions
	kvTotalNum := len(kvIDs)
	docs = make([]*model.KVDoc, kvTotalNum)
	tasks := make([]*sync.Task, kvTotalNum)
	tombstones := make([]*sync.Tombstone, kvTotalNum)
	successKVNum := 0
	for i := 0; i < kvTotalNum; i++ {
		kvDoc, err := getKVDoc(ctx, domain, project, kvIDs[i])
		// if not find the kv, continue
		if err != nil {
			if err == datasource.ErrKeyNotExists {
				openlog.Error(err.Error())
				continue
			}
			return nil, 0, err
		}
		if kvDoc == nil {
			continue
		}
		task, err := sync.NewTask(domain, project, sync.DeleteAction, datasource.ConfigResource, kvDoc)
		if err != nil {
			openlog.Error("fail to create task")
			return nil, 0, err
		}
		docs[successKVNum] = kvDoc
		tasks[successKVNum] = task
		tombstones[successKVNum] = sync.NewTombstone(domain, project, datasource.ConfigResource,
			datasource.TombstoneID(kvDoc))
		successKVNum++
	}
	if successKVNum == 0 {
		return nil, 0, datasource.ErrKeyNotExists
	}
	if successKVNum != kvTotalNum {
		docs = docs[:successKVNum]
		tasks = tasks[:successKVNum]
		tombstones = tombstones[:successKVNum]
	}
	for _, id := range kvIDs {
		opOptions = append(opOptions, etcdadpt.OpDel(etcdadpt.WithStrKey(key.KV(domain, project, id))))
	}
	for _, task := range tasks {
		taskBytes, err := json.Marshal(task)
		if err != nil {
			openlog.Error("fail to marshal task" + err.Error())
			return nil, 0, err
		}
		opOptions = append(opOptions, etcdadpt.OpPut(etcdadpt.WithStrKey(key.TaskKey(domain, project,
			task.ID, task.Timestamp)), etcdadpt.WithValue(taskBytes)))
	}
	for _, tombstone := range tombstones {
		tombstoneBytes, err := json.Marshal(tombstone)
		if err != nil {
			openlog.Error("fail to marshal tombstone" + err.Error())
			return nil, 0, err
		}
		opOptions = append(opOptions, etcdadpt.OpPut(etcdadpt.WithStrKey(key.TombstoneKey(domain, project,
			tombstone.ResourceType, tombstone.ResourceID)), etcdadpt.WithValue(tombstoneBytes)))
	}
	err := etcdadpt.Txn(ctx, opOptions)
	if err != nil {
		openlog.Error("find many and delete error", openlog.WithTags(openlog.Tags{
			"err": err.Error(),
		}))
		return nil, 0, err
	}
	return docs, int64(successKVNum), nil
}