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 }
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 }