func WalkViewInBatches(result chan cb.ViewRow, errs chan errors.Error, stop chan bool, bucket *cb.Bucket, ddoc string, view string, isPrimary bool, options map[string]interface{}, batchSize int64, limit int64) { if limit != 0 && limit < batchSize { batchSize = limit } defer close(result) defer close(errs) defer func() { r := recover() if r != nil { logging.Errorf("View Walking Panic: %v\n%s", r, debug.Stack()) errs <- errors.NewCbViewsAccessError(nil, "Panic In walking view "+view) } }() options["limit"] = batchSize + 1 numRead := int64(0) numSent := int64(0) keysSent := map[string]bool{} ok := true for ok { logURL, err := bucket.ViewURL(ddoc, view, options) if err == nil { logging.Debugf("Request View: %v", logURL) } vres, err := bucket.View(ddoc, view, options) if err != nil { errs <- errors.NewCbViewsAccessError(err, "View name "+view) return } for i, row := range vres.Rows { // dont process the last row, its just used to see if we // need to continue processing if int64(i) < batchSize { // Send the row if its primary key has not been sent if isPrimary || !keysSent[row.ID] { select { case result <- row: numSent += 1 case <-stop: ok = false break } } // For non primary views, mark the row's primary key as sent if !isPrimary { keysSent[row.ID] = true } numRead += 1 } } if (int64(len(vres.Rows)) > batchSize) && (limit == 0 || (limit != 0 && numRead < limit)) { // prepare for next run skey := vres.Rows[batchSize].Key skeydocid := vres.Rows[batchSize].ID options["startkey"] = skey options["startkey_docid"] = cb.DocID(skeydocid) } else { // stop ok = false } } logging.Debugf("WalkViewInBatches %s: %d rows fetched, %d rows sent", view, numRead, numSent) }
"github.com/couchbase/query/datastore" "github.com/couchbase/query/errors" "github.com/couchbase/query/logging" "github.com/couchbase/query/value" ) const NETWORK_CHANNEL = "NETWORK" const TYPE_NULL = 64 const TYPE_BOOLEAN = 96 const TYPE_NUMBER = 128 const TYPE_STRING = 160 const TYPE_ARRAY = 192 const TYPE_OBJECT = 224 var MIN_ID = cb.DocID("") var MAX_ID = cb.DocID(strings.Repeat(string([]byte{0xff}), 251)) func ViewTotalRows(bucket *cb.Bucket, ddoc string, view string, options map[string]interface{}) (int64, errors.Error) { options["limit"] = 0 logURL, err := bucket.ViewURL(ddoc, view, options) if err == nil { logging.Debugf("Request View: %v", logURL) } vres, err := bucket.View(ddoc, view, options) if err != nil { return 0, errors.NewCbViewsAccessError(err, "View Name"+view) } return int64(vres.TotalRows), nil