コード例 #1
0
ファイル: from.go プロジェクト: amarantha-k/query
/*
Qualify all identifiers for the parent expression. Checks for
duplicate aliases.
*/
func (this *SubqueryTerm) Formalize(parent *expression.Formalizer) (f *expression.Formalizer, err error) {
	err = this.subquery.Formalize()
	if err != nil {
		return
	}

	alias := this.Alias()
	if alias == "" {
		err = errors.NewError(nil, "FROM term must have a name or alias.")
		return
	}

	_, ok := parent.Allowed.Field(alias)
	if ok {
		err = errors.NewError(nil, fmt.Sprintf("Duplicate subquery alias %s.", alias))
		return nil, err
	}

	allowed := value.NewScopeValue(make(map[string]interface{}), parent.Allowed)
	allowed.SetField(alias, alias)

	f = expression.NewFormalizer()
	f.Keyspace = alias
	f.Allowed = allowed
	return
}
コード例 #2
0
ファイル: scan_index.go プロジェクト: amarantha-k/query
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
			}
		}
	})
}
コード例 #3
0
ファイル: from.go プロジェクト: amarantha-k/query
/*
Qualify all identifiers for the parent expression. Checks for
duplicate aliases.
*/
func (this *KeyspaceTerm) Formalize(parent *expression.Formalizer) (f *expression.Formalizer, err error) {
	keyspace := this.Alias()
	if keyspace == "" {
		err = errors.NewError(nil, "FROM term must have a name or alias.")
		return
	}

	if this.keys != nil {
		_, err = this.keys.Accept(parent)
		if err != nil {
			return
		}
	}

	_, ok := parent.Allowed.Field(keyspace)
	if ok {
		err = errors.NewError(nil, fmt.Sprintf("Duplicate subquery alias %s.", keyspace))
		return nil, err
	}

	allowed := value.NewScopeValue(make(map[string]interface{}), parent.Allowed)
	allowed.SetField(keyspace, keyspace)

	f = expression.NewFormalizer()
	f.Keyspace = keyspace
	f.Allowed = allowed
	return
}
コード例 #4
0
ファイル: scan_primary.go プロジェクト: amarantha-k/query
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
		}
	}
}
コード例 #5
0
ファイル: scan_key.go プロジェクト: amarantha-k/query
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
			}
		}
	})
}
コード例 #6
0
ファイル: update_util.go プロジェクト: amarantha-k/query
func buildFor(f *algebra.UpdateFor, val value.Value, arrays []value.Value, context *Context) ([]value.Value, error) {
	n := -1
	for _, a := range arrays {
		act := a.Actual()
		switch act := act.(type) {
		case []interface{}:
			if n < 0 || len(act) < n {
				n = len(act)
			}
		}
	}

	if n < 0 {
		return nil, nil
	}

	rv := make([]value.Value, n)
	for i, _ := range rv {
		rv[i] = value.NewScopeValue(make(map[string]interface{}, len(f.Bindings())), val)
		for j, b := range f.Bindings() {
			v, ok := arrays[j].Index(i)
			if ok {
				rv[i].SetField(b.Variable(), v)
			}
		}
	}

	return rv, nil
}
コード例 #7
0
ファイル: coll_every.go プロジェクト: amarantha-k/query
/*
This method evaluates the EVERY range predicate and returns a boolean
value representing the result. The first step is to accumulate the
elements or attributes of a collection/object. This is done by
ranging over the bindings, evaluating the expressions and populating
a slice of descendants if present. If any of these binding values are
mising or null then, return a missing/null. The next step is to get
the number of elements/attributes by ranging over the bindings slice.
In order to evaluate the every clause, evaluate the satisfies
condition with respect to the collection. If this returns false for
any condition, then return false (as every condition needs to evaluate
to true). If the condition over all elements/attributes have been
satisfied, return true.
*/
func (this *Every) Evaluate(item value.Value, context Context) (value.Value, error) {
	missing := false
	null := false

	barr := make([][]interface{}, len(this.bindings))
	for i, b := range this.bindings {
		bv, err := b.Expression().Evaluate(item, context)
		if err != nil {
			return nil, err
		}

		if b.Descend() {
			buffer := make([]interface{}, 0, 256)
			bv = value.NewValue(bv.Descendants(buffer))
		}

		switch bv.Type() {
		case value.ARRAY:
			barr[i] = bv.Actual().([]interface{})
		case value.MISSING:
			missing = true
		default:
			null = true
		}
	}

	if missing {
		return value.MISSING_VALUE, nil
	}

	if null {
		return value.NULL_VALUE, nil
	}

	n := -1
	for _, b := range barr {
		if n < 0 || len(b) < n {
			n = len(b)
		}
	}

	for i := 0; i < n; i++ {
		cv := value.NewScopeValue(make(map[string]interface{}, len(this.bindings)), item)
		for j, b := range this.bindings {
			cv.SetField(b.Variable(), barr[j][i])
		}

		sv, e := this.satisfies.Evaluate(cv, context)
		if e != nil {
			return nil, e
		}

		if !sv.Truth() {
			return value.NewValue(false), nil
		}
	}

	return value.NewValue(true), nil
}
コード例 #8
0
ファイル: scan_dummy.go プロジェクト: amarantha-k/query
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)
	})
}
コード例 #9
0
ファイル: project_initial.go プロジェクト: amarantha-k/query
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)
	}
}
コード例 #10
0
ファイル: scan_count.go プロジェクト: amarantha-k/query
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)
	})
}
コード例 #11
0
ファイル: let.go プロジェクト: amarantha-k/query
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)
}
コード例 #12
0
ファイル: formalizer.go プロジェクト: amarantha-k/query
/*
Visitor method for Bindings. Value is a new map from string
to interface which is populated using the bindings in the
scope of the parent which is listed by the value Allowed.
Bring the bindings that have parrent Allowed into scope.
*/
func (this *Formalizer) PushBindings(bindings Bindings) (sv *value.ScopeValue, err error) {
	sv = value.NewScopeValue(make(map[string]interface{}, len(bindings)), this.Allowed)

	var expr Expression
	for _, b := range bindings {
		_, ok := this.Allowed.Field(b.Variable())
		if ok {
			return nil, fmt.Errorf("Bind alias %s already in scope.", b.Variable())
		}

		expr, err = this.Map(b.Expression())
		if err != nil {
			return nil, err
		}

		b.SetExpression(expr)
		sv.SetField(b.Variable(), b.Variable())
	}

	this.Allowed = sv
	return sv, nil
}