// 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 }
// 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 }
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)) }
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)) }
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 } } }
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") } }
// 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 }