Ejemplo n.º 1
0
func (p *ParseClass) resolvePointer(ctx context.Context, r resolver.Resolver, field *graphql.Field) (interface{}, error) {
	fieldName := field.Name
	fieldInfo := p.class.Fields[fieldName]
	pc, err := NewParseClass(p.client, fieldInfo.TargetClass, p.schema)
	if err != nil {
		return nil, err
	}
	// only resolve if we can obtain the objectId
	data, ok := p.Data[fieldName]
	if !ok {
		return nil, nil
	}
	asMap, ok := data.(map[string]interface{})
	if !ok {
		return nil, nil
	}
	oid := asMap["objectId"]
	if oid == nil {
		return nil, nil
	}
	objectID, ok := oid.(string)
	if !ok {
		return nil, nil
	}
	if t, ok := tracer.FromContext(ctx); ok {
		t.IncQueries(1)
	}
	err = pc.client.GetClass(fieldInfo.TargetClass, objectID, &pc.Data)
	return pc, err
}
Ejemplo n.º 2
0
// ServeHTTP provides an entrypoint into a graphql executor. It pulls the query from
// the 'q' GET parameter.
func (h *ExecutorHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Access-Control-Allow-Headers", r.Header.Get("Access-Control-Request-Headers"))
	if r.Method == "OPTIONS" {
		w.WriteHeader(200)
		return
	}

	//TODO(tmc): reject non-GET/OPTIONS requests
	q := r.URL.Query().Get("q")
	log.Println("query:", q)
	operation, err := parser.ParseOperation([]byte(q))
	if err != nil {
		log.Println("error parsing:", err)
		writeErr(w, err)
		return
	}
	// if err := h.validator.Validate(operation); err != nil { writeErr(w, err); return }
	ctx := context.Background()
	if r.Header.Get("X-Trace-ID") != "" {
		t, err := tracer.FromRequest(r)
		if err == nil {
			ctx = tracer.NewContext(ctx, t)
		}
	}
	ctx = context.WithValue(ctx, "http_request", r)
	if r.Header.Get("X-GraphQL-Only-Parse") == "1" {
		writeJSONIndent(w, operation, " ")
		return
	}

	data, err := h.executor.HandleOperation(ctx, operation)
	result := Result{Data: data}
	if err != nil {
		w.WriteHeader(400)
		result.Error = &Error{Message: err.Error()}
	}
	if t, ok := tracer.FromContext(ctx); ok {
		t.Done()
		result.Trace = t
	}

	writeJSONIndent(w, result, "  ")
}
Ejemplo n.º 3
0
func (p *ParseClass) get(ctx context.Context, r resolver.Resolver, f *graphql.Field) (interface{}, error) {
	var results []map[string]interface{}

	// TODO(tmc): handle overlap between special fields and user defined fields on a class elegantly
	whereClause := make(map[string]interface{})
	for _, a := range f.Arguments {
		// only populate where clause if the field isn't in out special field list
		if !specialFieldsSet[a.Name] {
			whereClause[a.Name] = a.Value
		}
	}
	if explicitWhere, ok := f.Arguments.Get("where"); ok {
		asMap, ok := explicitWhere.(map[string]interface{})
		if !ok {
			return nil, fmt.Errorf("explicit where fields must be maps, got '%T'", explicitWhere)
		}
		whereClause = asMap
	}
	whereJSON, err := json.Marshal(whereClause)
	if err != nil {
		return nil, err
	}
	// limit
	limit := DefaultLimit
	if l, ok := f.Arguments.Get("limit"); ok {
		if lim, ok := l.(int); ok {
			limit = lim
		} else {
			return nil, fmt.Errorf("'limit' argument should be an integer. Got %#v", l)
		}
	}

	// order
	order := ""
	if o, ok := f.Arguments.Get("order"); ok {
		if orderStr, ok := o.(string); ok {
			order = orderStr
		} else {
			return nil, fmt.Errorf("'order' argument should be a string. Got %#v", o)
		}
	}
	spew.Dump("ORDER:", order, f.Arguments)
	query := &parse.QueryOptions{
		Where: string(whereJSON),
		Limit: limit,
		Order: order,
	}
	if t, ok := tracer.FromContext(ctx); ok {
		t.IncQueries(1)
	}
	if err := p.client.QueryClass(p.class.ClassName, query, &results); err != nil {
		return nil, err
	}
	typedResults := make([]*ParseClass, 0, len(results))

	for _, r := range results {
		pc, err := NewParseClass(p.client, p.class.ClassName, p.schema)
		if err != nil {
			return nil, err
		}
		pc.Data = r
		typedResults = append(typedResults, pc)
	}

	return typedResults, err
}