func (b *keyspace) Fetch(keys []string) ([]datastore.AnnotatedPair, errors.Error) { if len(keys) == 0 { return nil, errors.NewCbNoKeysFetchError(nil, ":(") } bulkResponse, err := b.cbbucket.GetBulk(keys) if err != nil { // Ignore "Not found" keys if !isNotFoundError(err) { return nil, errors.NewCbBulkGetError(err, "") } } i := 0 rv := make([]datastore.AnnotatedPair, len(bulkResponse)) for k, v := range bulkResponse { var doc datastore.AnnotatedPair doc.Key = k Value := value.NewAnnotatedValue(value.NewValue(v.Body)) meta_flags := binary.BigEndian.Uint32(v.Extras[0:4]) meta_type := "json" if Value.Type() == value.BINARY { meta_type = "base64" } Value.SetAttachment("meta", map[string]interface{}{ "id": k, "cas": float64(v.Cas), "type": meta_type, "flags": float64(meta_flags), }) logging.Debugf("CAS Value for key %v is %v", k, float64(v.Cas)) doc.Value = Value rv[i] = doc i++ } logging.Debugf("Fetched %d keys ", i) return rv, nil }
func (vi *viewIndex) Scan(span *datastore.Span, distinct bool, limit int64, cons datastore.ScanConsistency, vector timestamp.Vector, conn *datastore.IndexConnection) { defer close(conn.EntryChannel()) // For primary indexes, bounds must always be strings, so we // can just enforce that directly viewOptions := map[string]interface{}{} viewOptions = generateViewOptions(cons, span) /*span.Range.Low, span.Range.High, span.Range.Inclusion) */ viewRowChannel := make(chan cb.ViewRow) viewErrChannel := make(chan errors.Error) go WalkViewInBatches(viewRowChannel, viewErrChannel, vi.keyspace.cbbucket, vi.DDocName(), vi.ViewName(), viewOptions, 1000, limit) var viewRow cb.ViewRow var err errors.Error sentRows := false ok := true numRows := 0 for ok { select { case viewRow, ok = <-viewRowChannel: if ok { entry := datastore.IndexEntry{PrimaryKey: viewRow.ID} // try to add the view row key as the entry key (unless this is _all_docs) if vi.DDocName() != "" /* FIXME && vi.IsPrimary() == false */ { lookupValue, err := convertCouchbaseViewKeyToLookupValue(viewRow.Key) if err == nil { entry.EntryKey = lookupValue } else { logging.Debugf("unable to convert index key to lookup value err:%v key %v", err, viewRow.Key) } } conn.EntryChannel() <- &entry sentRows = true numRows++ } case err, ok = <-viewErrChannel: if err != nil { logging.Errorf("%v", err) // check to possibly detect a bucket that was already deleted if !sentRows { logging.Infof("Checking bucket URI: %v", vi.keyspace.cbbucket.URI) _, err := http.Get(vi.keyspace.cbbucket.URI) if err != nil { logging.Errorf("%v", err) // remove this specific bucket from the pool cache vi.keyspace.namespace.lock.Lock() delete(vi.keyspace.namespace.keyspaceCache, vi.keyspace.Name()) vi.keyspace.namespace.lock.Unlock() // close this bucket vi.keyspace.Release() // ask the pool to refresh vi.keyspace.namespace.refresh(true) // bucket doesnt exist any more conn.Error(errors.NewCbViewsAccessError(nil, "keyspace "+vi.keyspace.Name())) return } } conn.Error(err) return } } } logging.Infof("Number of entries fetched from the index %d", numRows) }