// toProto converts the query to a protocol buffer.
func (q *Query) toProto(appID string) (*pb.Query, os.Error) {
	if q.kind == "" {
		return nil, os.NewError("datastore: empty query kind")
	}
	x := &pb.Query{
		App:  proto.String(appID),
		Kind: proto.String(q.kind),
	}
	if q.ancestor != nil {
		x.Ancestor = keyToProto(appID, q.ancestor)
	}
	if q.keysOnly {
		x.KeysOnly = proto.Bool(true)
		x.RequirePerfectPlan = proto.Bool(true)
	}
	for _, qf := range q.filter {
		if qf.FieldName == "" {
			return nil, os.NewError("datastore: empty query filter field name")
		}
		p, errStr := valueToProto(appID, qf.FieldName, reflect.ValueOf(qf.Value), false)
		if errStr != "" {
			return nil, os.NewError("datastore: bad query filter value type: " + errStr)
		}
		xf := &pb.Query_Filter{
			Op:       operatorToProto[qf.Op],
			Property: []*pb.Property{p},
		}
		if xf.Op == nil {
			return nil, os.NewError("datastore: unknown query filter operator")
		}
		x.Filter = append(x.Filter, xf)
	}
	for _, qo := range q.order {
		if qo.FieldName == "" {
			return nil, os.NewError("datastore: empty query order field name")
		}
		xo := &pb.Query_Order{
			Property:  proto.String(qo.FieldName),
			Direction: sortDirectionToProto[qo.Direction],
		}
		if xo.Direction == nil {
			return nil, os.NewError("datastore: unknown query order direction")
		}
		x.Order = append(x.Order, xo)
	}
	if q.limit != 0 {
		x.Limit = proto.Int(q.limit)
	}
	if q.offset != 0 {
		x.Offset = proto.Int(q.offset)
	}
	return x, nil
}
Beispiel #2
0
// Reads a single arbitrary type and returns the proper StateValue.
func readField(val reflect.Value) *protocol.StateValue {
	msg := &protocol.StateValue{}
	switch f := val.(type) {
	case *reflect.BoolValue:
		msg.Type = protocol.NewStateValue_Type(protocol.StateValue_BOOL)
		msg.BoolVal = proto.Bool(f.Get())
	case *reflect.IntValue:
		msg.Type = protocol.NewStateValue_Type(protocol.StateValue_INT)
		msg.IntVal = proto.Int(int(f.Get()))
	case *reflect.FloatValue:
		msg.Type = protocol.NewStateValue_Type(protocol.StateValue_FLOAT)
		msg.FloatVal = proto.Float32(float32(f.Get()))
	case *reflect.StringValue:
		msg.Type = protocol.NewStateValue_Type(protocol.StateValue_STRING)
		msg.StringVal = proto.String(f.Get())
	case *reflect.SliceValue:
		msg.Type = protocol.NewStateValue_Type(protocol.StateValue_ARRAY)
		msg.ArrayVal = makeStateValueArray(f, f.Len())
	case *reflect.StructValue:
		msg = readStructField(f)
	case *reflect.PtrValue:
		return readField(reflect.Indirect(f)) // Dereference and recurse
	default:
		panic("State value not supported: " + val.Type().String())
	}
	return msg
}
Beispiel #3
0
func TestPtrFieldState(t *testing.T) {
	num := 9
	state := ptrFieldState{&num}
	sv := &protocol.StateValue{}
	sv.Type = protocol.NewStateValue_Type(protocol.StateValue_INT)
	sv.IntVal = proto.Int(*state.Value)

	equalOrError(t, sv, packState(state))
}
Beispiel #4
0
func TestSingleFieldState(t *testing.T) {
	// testState is made available by observer_test.go
	state := testState{9}
	sv := &protocol.StateValue{}
	sv.Type = protocol.NewStateValue_Type(protocol.StateValue_INT)
	sv.IntVal = proto.Int(state.Value)

	equalOrError(t, sv, packState(state))
}
Beispiel #5
0
func (self *WaveletNode) post(req *PostRequest) {
	docuri := req.URI.(DocumentURI)

	// Request is not aimed at this document?
	if len(docuri.NameSeq) != self.level {
		makeErrorResponse(req.Response, "Document "+docuri.NameSeq[self.level]+" does not exist")
		req.FinishSignal <- false
		return
	}
	log.Println("Wavelet is handling a post: ", req.URI)

	switch req.Origin {
	// A message from the client. It must be a ProtocolWaveletDelta
	case ClientOrigin:
		if req.MimeType != "application/json-wave" {
			makeClientErrorResponse(req.Response, "Data type "+req.MimeType+" not allowed for put/post")
			req.FinishSignal <- false
		}
		submit := &ClientSubmitRequest{}
		if err := Unmarshal(req.Data, submit); err != nil {
			makeClientErrorResponse(req.Response, "Cannot parse HTTP body. No valid ProtoBuf or wrong message type: "+err.String())
			req.FinishSignal <- false
			return
		}
		if !self.apply(submit.Delta) {
			makeClientErrorResponse(req.Response, "Could not apply document mutation")
			req.FinishSignal <- false
			return
		}
		response := &ClientSubmitResponse{}
		response.OperationsApplied = proto.Int(len(submit.Delta.Operation))
		// TODO: time stamp
		response.HashedVersionAfterApplication = &self.wavelet.HashedVersion
		var buffer bytes.Buffer
		Marshal(response, &buffer)
		req.Response.SetHeader("Content-Type", "application/json")
		if _, err := req.Response.Write(buffer.Bytes()); err != nil {
			log.Println("Failed writing HTTP response")
			req.FinishSignal <- false
			return
		}
		req.FinishSignal <- true
	// A message via federation
	case FederationOrigin:
		if self.IsLocal() {
			// This server is the hosting server?
			// It must be a ProtocolSignedDelta
			// TODO
		} else {
			// This server is the remote server?
			// It must be a ProtocolAppliedWaveletDelta
			// TODO
		}
	}
}
Beispiel #6
0
func makeClientErrorResponse(res http.ResponseWriter, errorText string) {
	log.Println(errorText)
	response := &ClientSubmitResponse{}
	response.OperationsApplied = proto.Int(0)
	response.ErrorMessage = proto.String(errorText)
	var buffer bytes.Buffer
	err := Marshal(response, &buffer)
	if err != nil {
		panic("Failed marshaling")
	}
	res.SetHeader("Content-Type", "application/json")
	_, err = res.Write(buffer.Bytes())
	if err != nil {
		log.Println("Failed writing HTTP response")
	}
}
Beispiel #7
0
// Returns a StateValue with IntVal set to the passed value x
func makeIntValMsg(x int) *protocol.StateValue {
	sv := &protocol.StateValue{}
	sv.Type = protocol.NewStateValue_Type(protocol.StateValue_INT)
	sv.IntVal = proto.Int(x)
	return sv
}