func (this *KeyScan) RunOnce(context *Context, parent value.Value) { this.once.Do(func() { defer context.Recover() // Recover from any panic defer close(this.itemChannel) // Broadcast that I have stopped defer this.notify() // Notify that I have stopped keys, e := this.plan.Keys().Evaluate(parent, context) if e != nil { context.Error(errors.NewError(e, "Error evaluating KEYS.")) return } actuals := keys.Actual() switch actuals.(type) { case []interface{}: case nil: actuals = []interface{}(nil) default: actuals = []interface{}{actuals} } acts := actuals.([]interface{}) for _, key := range acts { cv := value.NewScopeValue(make(map[string]interface{}), parent) av := value.NewAnnotatedValue(cv) av.SetAttachment("meta", map[string]interface{}{"id": key}) if !this.sendItem(av) { return } } }) }
func (this *PrimaryScan) scanPrimary(context *Context, parent value.Value) { conn := datastore.NewIndexConnection(context) defer notifyConn(conn) // Notify index that I have stopped go this.scanEntries(context, conn) var entry *datastore.IndexEntry ok := true for ok { select { case <-this.stopChannel: return default: } select { case entry, ok = <-conn.EntryChannel(): if ok { cv := value.NewScopeValue(make(map[string]interface{}), parent) av := value.NewAnnotatedValue(cv) av.SetAttachment("meta", map[string]interface{}{"id": entry.PrimaryKey}) ok = this.sendItem(av) } case <-this.stopChannel: return } } }
func (this *ValueScan) RunOnce(context *Context, parent value.Value) { this.once.Do(func() { defer context.Recover() // Recover from any panic defer close(this.itemChannel) // Broadcast that I have stopped defer this.notify() // Notify that I have stopped pairs := this.plan.Values() for _, pair := range pairs { key, err := pair.Key.Evaluate(parent, context) if err != nil { context.Error(errors.NewError(err, "Error evaluating VALUES.")) return } val, err := pair.Value.Evaluate(parent, context) if err != nil { context.Error(errors.NewError(err, "Error evaluating VALUES.")) return } av := value.NewAnnotatedValue(nil) av.SetAttachment("key", key) av.SetAttachment("value", val) if !this.sendItem(av) { return } } }) }
func (this *spanScan) RunOnce(context *Context, parent value.Value) { this.once.Do(func() { defer context.Recover() // Recover from any panic defer close(this.itemChannel) // Broadcast that I have stopped defer this.notify() // Notify that I have stopped conn := datastore.NewIndexConnection(context) defer notifyConn(conn) // Notify index that I have stopped go this.scan(context, conn) var entry *datastore.IndexEntry ok := true for ok { select { case <-this.stopChannel: return default: } select { case entry, ok = <-conn.EntryChannel(): if ok { cv := value.NewScopeValue(make(map[string]interface{}), parent) av := value.NewAnnotatedValue(cv) av.SetAttachment("meta", map[string]interface{}{"id": entry.PrimaryKey}) ok = this.sendItem(av) } case <-this.stopChannel: return } } }) }
func (this *InitialProject) processItem(item value.AnnotatedValue, context *Context) bool { terms := this.plan.Terms() n := len(terms) if n > 1 { return this.processTerms(item, context) } if n == 0 { return this.sendItem(item) } // n == 1 result := terms[0].Result() expr := result.Expression() if expr == nil { // Unprefixed star if item.Type() == value.OBJECT { return this.sendItem(item) } else { return this.sendItem(_EMPTY_ANNOTATED_VALUE) } } else if this.plan.Projection().Raw() { // Raw projection of an expression v, err := expr.Evaluate(item, context) if err != nil { context.Error(errors.NewError(err, "Error evaluating projection.")) return false } if result.As() == "" { return this.sendItem(value.NewAnnotatedValue(v)) } sv := value.NewScopeValue(make(map[string]interface{}, 1), item) sv.SetField(result.As(), v) av := value.NewAnnotatedValue(sv) av.SetAttachment("projection", v) return this.sendItem(av) } else { // Any other projection return this.processTerms(item, context) } }
func (this *FinalProject) processItem(item value.AnnotatedValue, context *Context) bool { pv := item.GetAttachment("projection") if pv != nil { v := pv.(value.Value) return this.sendItem(value.NewAnnotatedValue(v)) } return this.sendItem(item) }
func (this *InitialProject) processTerms(item value.AnnotatedValue, context *Context) bool { n := len(this.plan.Terms()) var f map[string]interface{} if item.Type() == value.OBJECT { f = item.Copy().Fields() } if f == nil { f = make(map[string]interface{}, n) } pv := value.NewAnnotatedValue(f) pv.SetAttachments(item.Attachments()) p := value.NewValue(make(map[string]interface{}, n+32)) pv.SetAttachment("projection", p) for _, term := range this.plan.Terms() { if term.Result().Alias() != "" { v, err := term.Result().Expression().Evaluate(item, context) if err != nil { context.Error(errors.NewError(err, "Error evaluating projection.")) return false } p.SetField(term.Result().Alias(), v) // Explicit aliases override data if term.Result().As() != "" { pv.SetField(term.Result().As(), v) } } else { // Star starval := item.GetValue() if term.Result().Expression() != nil { var err error starval, err = term.Result().Expression().Evaluate(item, context) if err != nil { context.Error(errors.NewError(err, "Error evaluating projection.")) return false } } // Latest star overwrites previous star switch sa := starval.Actual().(type) { case map[string]interface{}: for k, v := range sa { p.SetField(k, v) } } } } return this.sendItem(pv) }
func (this *Prepare) RunOnce(context *Context, parent value.Value) { this.once.Do(func() { defer context.Recover() // Recover from any panic defer close(this.itemChannel) // Broadcast that I have stopped defer this.notify() // Notify that I have stopped value := value.NewAnnotatedValue(this.plan) this.sendItem(value) }) }
func (b *storeKeyspace) fetchOne(key string) (value.AnnotatedValue, errors.Error) { if key == b.namespace.store.actualStore.Id() { doc := value.NewAnnotatedValue(map[string]interface{}{ "id": b.namespace.store.actualStore.Id(), "url": b.namespace.store.actualStore.URL(), }) return doc, nil } return nil, errors.NewSystemDatastoreError(nil, "Key Not Found "+key) }
// generate a mock document - used by fetchOne to mock a document in the keyspace func genItem(i int, nitems int) (value.AnnotatedValue, errors.Error) { if i < 0 || i >= nitems { return nil, errors.NewOtherDatastoreError(nil, fmt.Sprintf("item out of mock range: %v [0,%v)", i, nitems)) } id := strconv.Itoa(i) doc := value.NewAnnotatedValue(map[string]interface{}{"id": id, "i": float64(i)}) doc.SetAttachment("meta", map[string]interface{}{"id": id}) return doc, nil }
func (this *DummyScan) RunOnce(context *Context, parent value.Value) { this.once.Do(func() { defer context.Recover() // Recover from any panic defer close(this.itemChannel) // Broadcast that I have stopped defer this.notify() // Notify that I have stopped cv := value.NewScopeValue(nil, parent) av := value.NewAnnotatedValue(cv) this.sendItem(av) }) }
func (b *namespaceKeyspace) fetchOne(key string) (value.AnnotatedValue, errors.Error) { namespace, excp := b.namespace.store.actualStore.NamespaceById(key) if namespace != nil { doc := value.NewAnnotatedValue(map[string]interface{}{ "id": namespace.Id(), "name": namespace.Name(), "datastore_id": b.namespace.store.actualStore.Id(), }) return doc, nil } return nil, errors.NewSystemDatastoreError(excp, "Key Not Found "+key) }
/* Add input item to the cumulative set. Get the set. If no errors enountered add the item to the set and return it. If set has not been initialized yet, create a new set with capacity _OBJECT_CAP and add the item. Return the set value. */ func setAdd(item, cumulative value.Value) (value.Value, error) { set, e := getSet(cumulative) if e == nil { set.Add(item) return cumulative, nil } set = value.NewSet(_OBJECT_CAP) set.Add(item) av := value.NewAnnotatedValue(nil) av.SetAttachment("set", set) return av, nil }
func (this *Distinct) afterItems(context *Context) { if this.collect { return } for _, av := range this.set.Values() { if !this.sendItem(value.NewAnnotatedValue(av)) { return } } this.set = nil }
func (b *indexKeyspace) fetchOne(key string) ([]datastore.AnnotatedPair, errors.Error) { rv := make([]datastore.AnnotatedPair, 0, 2) ids := strings.SplitN(key, "/", 3) actualStore := b.namespace.store.actualStore namespace, err := actualStore.NamespaceById(ids[0]) if err != nil { return nil, err } keyspace, err := namespace.KeyspaceById(ids[1]) if err != nil { return nil, err } indexers, err := keyspace.Indexers() if err != nil { return nil, err } for _, indexer := range indexers { index, err := indexer.IndexById(ids[2]) if err != nil { continue } state, msg, err := index.State() if err != nil { return nil, err } doc := value.NewAnnotatedValue(map[string]interface{}{ "id": index.Id(), "name": index.Name(), "keyspace_id": keyspace.Id(), "namespace_id": namespace.Id(), "datastore_id": actualStore.Id(), "index_key": datastoreObjectToJSONSafe(indexKeyToIndexKeyStringArray(index.RangeKey())), "using": datastoreObjectToJSONSafe(index.Type()), "state": string(state), }) if msg != "" { doc.SetField("message", msg) } rv = append(rv, datastore.AnnotatedPair{key, doc}) } return rv, nil }
func (this *Merge) processMatch(item value.AnnotatedValue, context *Context, update, delete, insert Operator) bool { kv, e := this.plan.Key().Evaluate(item, context) if e != nil { context.Error(errors.NewError(e, "Error evaluatating MERGE key.")) return false } ka := kv.Actual() k, ok := ka.(string) if !ok { context.Error(errors.NewError(nil, fmt.Sprintf("Invalid MERGE key %v of type %T.", ka, ka))) return false } bvs, err := this.plan.Keyspace().Fetch([]string{k}) if err != nil { context.Error(err) return false } if len(bvs) > 0 { bv := bvs[0].Value // Matched; join source and target if update != nil { item.SetAttachment("target", bv) } abv := value.NewAnnotatedValue(bv) item.SetField(this.plan.KeyspaceRef().Alias(), abv) // Perform UPDATE and/or DELETE if update != nil { update.Input().ItemChannel() <- item } if delete != nil { delete.Input().ItemChannel() <- item } } else { // Not matched; INSERT if insert != nil { insert.Input().ItemChannel() <- item } } return true }
func fetch(path string) (item value.AnnotatedValue, e errors.Error) { bytes, er := ioutil.ReadFile(path) if er != nil { if os.IsNotExist(er) { // file doesn't exist should simply return nil, nil return } return nil, errors.NewFileDatastoreError(er, "") } doc := value.NewAnnotatedValue(value.NewValue(bytes)) doc.SetAttachment("meta", map[string]interface{}{"id": documentPathToId(path)}) item = doc return }
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 (this *Explain) RunOnce(context *Context, parent value.Value) { this.once.Do(func() { defer context.Recover() // Recover from any panic defer close(this.itemChannel) // Broadcast that I have stopped defer this.notify() // Notify that I have stopped bytes, err := json.Marshal(this.plan) if err != nil { context.Fatal(errors.NewError(err, "Failed to marshal JSON.")) return } value := value.NewAnnotatedValue(bytes) this.sendItem(value) }) }
func (this *CountScan) RunOnce(context *Context, parent value.Value) { this.once.Do(func() { defer context.Recover() // Recover from any panic defer close(this.itemChannel) // Broadcast that I have stopped defer this.notify() // Notify that I have stopped count, e := this.plan.Keyspace().Count() if e != nil { context.Error(e) return } cv := value.NewScopeValue(nil, parent) av := value.NewAnnotatedValue(cv) av.SetAttachment("count", value.NewValue(count)) this.sendItem(av) }) }
func (b *keyspaceKeyspace) fetchOne(key string) (value.AnnotatedValue, errors.Error) { ids := strings.SplitN(key, "/", 2) namespace, err := b.namespace.store.actualStore.NamespaceById(ids[0]) if namespace != nil { keyspace, _ := namespace.KeyspaceById(ids[1]) if keyspace != nil { doc := value.NewAnnotatedValue(map[string]interface{}{ "id": keyspace.Id(), "name": keyspace.Name(), "namespace_id": namespace.Id(), "datastore_id": b.namespace.store.actualStore.Id(), }) return doc, nil } } return nil, err }
func (this *Let) processItem(item value.AnnotatedValue, context *Context) bool { n := len(this.plan.Bindings()) cv := value.NewScopeValue(make(map[string]interface{}, n), item) lv := value.NewAnnotatedValue(cv) lv.SetAttachments(item.Attachments()) for _, b := range this.plan.Bindings() { v, e := b.Expression().Evaluate(item, context) if e != nil { context.Error(errors.NewError(e, "Error evaluating LET.")) return false } lv.SetField(b.Variable(), v) } return this.sendItem(lv) }
func (this *FinalGroup) afterItems(context *Context) { if len(this.groups) > 0 { for _, av := range this.groups { if !this.sendItem(av) { return } } } else if this.plan.Keys() == nil { // Grouping over all inputs -- always send a result av := value.NewAnnotatedValue(nil) aggregates := make(map[string]value.Value, len(this.plan.Aggregates())) av.SetAttachment("aggregates", aggregates) for _, agg := range this.plan.Aggregates() { aggregates[agg.String()] = agg.Default() } this.sendItem(av) } }
func (this *Unnest) processItem(item value.AnnotatedValue, context *Context) bool { ev, err := this.plan.Term().Expression().Evaluate(item, context) if err != nil { context.Error(errors.NewError(err, "Error evaluating UNNEST path.")) return false } actuals := ev.Actual() switch actuals.(type) { case []interface{}: case nil: actuals = []interface{}(nil) default: actuals = []interface{}{actuals} } acts := actuals.([]interface{}) if len(acts) == 0 { // Outer unnest return !this.plan.Term().Outer() || this.sendItem(item) } // Attach and send for i, act := range acts { var av value.AnnotatedValue if i < len(acts)-1 { av = value.NewAnnotatedValue(item.Copy()) } else { av = item } av.SetField(this.plan.Alias(), value.NewValue(act)) if !this.sendItem(av) { return false } } return true }
func setPath(t *algebra.SetTerm, clone, item value.AnnotatedValue, context *Context) (value.AnnotatedValue, error) { if t.UpdateFor() != nil { return setFor(t, clone, item, context) } v, err := t.Value().Evaluate(item, context) if err != nil { return nil, err } if v.Type() == value.MISSING { } if t.Path() != nil { t.Path().Set(clone, v, context) return clone, nil } else { av := value.NewAnnotatedValue(v) av.SetAttachments(clone.Attachments()) return av, nil } }
func (this *Alias) processItem(item value.AnnotatedValue, context *Context) bool { av := value.NewAnnotatedValue(make(map[string]interface{})) av.SetAttachments(item.Attachments()) av.SetField(this.plan.Alias(), item) return this.sendItem(av) }
func (this *Nest) processItem(item value.AnnotatedValue, context *Context) bool { kv, e := this.plan.Term().Keys().Evaluate(item, context) if e != nil { context.Error(errors.NewError(e, "Error evaluating NEST keys.")) return false } actuals := kv.Actual() switch actuals.(type) { case []interface{}: case nil: actuals = []interface{}(nil) default: actuals = []interface{}{actuals} } acts := actuals.([]interface{}) if len(acts) == 0 { // Outer nest return !this.plan.Outer() || this.sendItem(item) } // Build list of keys keys := make([]string, 0, len(acts)) for _, key := range acts { k := value.NewValue(key).Actual() switch k := k.(type) { case string: keys = append(keys, k) } } // Fetch pairs, err := this.plan.Keyspace().Fetch(keys) if err != nil { context.Error(err) return false } found := len(pairs) > 0 if !found && !this.plan.Outer() { return true } nvs := make([]interface{}, 0, len(pairs)) for i, pair := range pairs { nestItem := pair.Value var nv value.AnnotatedValue // Apply projection, if any projection := this.plan.Term().Projection() if projection != nil { projectedItem, e := projection.Evaluate(nestItem, context) if e != nil { context.Error(errors.NewError(e, "Error evaluating nest path.")) return false } if projectedItem.Type() == value.MISSING { continue } nv = value.NewAnnotatedValue(projectedItem) } else { nv = value.NewAnnotatedValue(nestItem) } nv.SetAttachment("meta", map[string]interface{}{"id": keys[i]}) nvs = append(nvs, nv) } // Attach and send item.SetField(this.plan.Term().Alias(), nvs) return this.sendItem(item) }
func (b *dualKeyspace) fetchOne(key string) (value.AnnotatedValue, errors.Error) { return value.NewAnnotatedValue(nil), nil }
func (this *SendInsert) flushBatch(context *Context) bool { if len(this.batch) == 0 { return true } keyExpr := this.plan.Key() valExpr := this.plan.Value() dpairs := make([]datastore.Pair, len(this.batch)) var key, val value.Value var err error var ok bool i := 0 for _, av := range this.batch { dpair := &dpairs[i] if keyExpr != nil { // INSERT ... SELECT key, err = keyExpr.Evaluate(av, context) if err != nil { context.Error(errors.NewError(err, fmt.Sprintf("Error evaluating INSERT key for %v", av.GetValue()))) continue } if valExpr != nil { val, err = valExpr.Evaluate(av, context) if err != nil { context.Error(errors.NewError(err, fmt.Sprintf("Error evaluating INSERT value for %v", av.GetValue()))) continue } } else { val = av } } else { // INSERT ... VALUES key, ok = av.GetAttachment("key").(value.Value) if !ok { context.Error(errors.NewError(nil, fmt.Sprintf("No INSERT key for %v", av.GetValue()))) continue } val, ok = av.GetAttachment("value").(value.Value) if !ok { context.Error(errors.NewError(nil, fmt.Sprintf("No INSERT value for %v", av.GetValue()))) continue } } dpair.Key, ok = key.Actual().(string) if !ok { context.Error(errors.NewError(nil, fmt.Sprintf("Cannot INSERT non-string key %v of type %T.", key, key))) continue } dpair.Value = val i++ } dpairs = dpairs[0:i] this.batch = nil // Perform the actual INSERT keys, e := this.plan.Keyspace().Insert(dpairs) // Update mutation count with number of inserted docs context.AddMutationCount(uint64(len(keys))) if e != nil { context.Error(e) } // Capture the inserted keys in case there is a RETURNING clause for i, k := range keys { av := value.NewAnnotatedValue(make(map[string]interface{})) av.SetAttachment("meta", map[string]interface{}{"id": k}) av.SetField(this.plan.Alias(), dpairs[i].Value) if !this.sendItem(av) { return false } } return true }
func (this *Fetch) flushBatch(context *Context) bool { if len(this.batch) == 0 { return true } // Build list of keys keys := make([]string, len(this.batch)) for i, av := range this.batch { meta := av.GetAttachment("meta") switch meta := meta.(type) { case map[string]interface{}: key := meta["id"] act := value.NewValue(key).Actual() switch act := act.(type) { case string: keys[i] = act default: context.Error(errors.NewError(nil, fmt.Sprintf( "Missing or invalid primary key %v of type %T.", act, act))) return false } default: context.Error(errors.NewError(nil, "Missing or invalid meta for primary key.")) return false } } // Fetch pairs, err := this.plan.Keyspace().Fetch(keys) if err != nil { context.Error(err) return false } // Attach meta and send for i, pair := range pairs { item := pair.Value var fv value.AnnotatedValue // Apply projection, if any projection := this.plan.Term().Projection() if projection != nil { projectedItem, e := projection.Evaluate(item, context) if e != nil { context.Error(errors.NewError(e, "Error evaluating fetch path.")) return false } if projectedItem.Type() == value.MISSING { continue } fv = value.NewAnnotatedValue(projectedItem) } else { fv = value.NewAnnotatedValue(item) } av := this.batch[i] switch item := item.(type) { case value.AnnotatedValue: meta := item.(value.AnnotatedValue).GetAttachment("meta") fv.SetAttachment("meta", meta) default: fv.SetAttachment("meta", av.GetAttachment("meta")) } av.SetField(this.plan.Term().Alias(), fv) if !this.sendItem(av) { return false } } return true }