Пример #1
0
func deleteChildrenForPathInBatch(
	batch *sublevel.SuperBatch,
	path string,
	updateSeq *uint64,
	bump bool,
) error {
	/* iterate through all children (/something/here, /something/else/where etc.)
	   do not iterate through this same "base" path.
	   save the fetched paths in a bucket from which we will then bump their revs.
	*/
	toDelete := make(map[string]bool)
	docs := db.Sub(DOC_STORE)
	iter := docs.NewIterator(util.BytesPrefix([]byte(path+"/")), nil)
	for iter.Next() {
		subpath := string(iter.Key())

		/* for special values, those starting with "_", we remove the last key of
		   path so we can guarantee that intermediate keys with no value also have
		   their revs bumped. we can trust this because these intermediate paths will
		   always have a _rev (and sometimes a _deleted) */
		pathKeys := SplitKeys(subpath)
		if pathKeys[len(pathKeys)-1][0] == '_' {
			toDelete[JoinKeys(pathKeys[:len(pathKeys)-1])] = true
		} else {
			toDelete[subpath] = true
		}
	}
	iter.Release()
	err := iter.Error()
	if err != nil {
		log.Error("delete children iteration failed: ", err)
		return err
	}

	for subpath := range toDelete {
		batch.Delete(DOC_STORE, []byte(subpath))
		batch.Put(DOC_STORE, []byte(subpath+"/_deleted"), []byte(nil))
	}

	// we will not bump revisions or seqs unless this flag is true
	// it should be false if we are doing a RESET
	if bump {
		for subpath := range toDelete {
			*updateSeq++
			bumpPathInBatch(batch, subpath, "", false, *updateSeq)
		}
	}

	return nil
}
Пример #2
0
func bumpPathInBatch(
	batch *sublevel.SuperBatch,
	path string,
	currentrev string,
	forcerev bool,
	newseq uint64,
) (newrev string) {
	// bumping rev
	if forcerev {
		newrev = currentrev
	} else {
		if currentrev == "" {
			/* no rev was passed, we will fetch our current rev
			   and bump accordingly */
			currentrev = string(GetRev(path))
		}
		newrev = NewRev(currentrev)
	}

	batch.Put(DOC_STORE, []byte(path+"/_rev"), []byte(newrev))
	batch.Put(REV_STORE, []byte(path+"::"+newrev), []byte{})

	// bumping seq
	pathkeys := SplitKeys(path)
	nkeys := len(pathkeys)
	basekey := JoinKeys(pathkeys[:nkeys-1])
	lastkey := pathkeys[nkeys-1]
	batch.Put(BY_SEQ, []byte(fmt.Sprintf("%s::%016d", basekey, newseq)), []byte(lastkey+"::"+newrev))

	return newrev
}