diff --git a/gql/parser.go b/gql/parser.go index 42b099fd75fe6e49f79875f06439a5e08558964c..2f7cc1111685d2fe21b6308e7c12d0e75fbe458e 100644 --- a/gql/parser.go +++ b/gql/parser.go @@ -33,6 +33,7 @@ type GraphQuery struct { UID uint64 XID string Attr string + First int Children []*GraphQuery } @@ -41,6 +42,11 @@ type Mutation struct { Del string } +type pair struct { + Key string + Val string +} + func run(l *lex.Lexer) { for state := lexText; state != nil; { state = state(l) @@ -142,6 +148,35 @@ func parseMutationOp(l *lex.Lexer, op string, mu *Mutation) error { return errors.New("Invalid mutation formatting.") } +func parseArguments(l *lex.Lexer) (result []pair, rerr error) { + for { + var p pair + + // Get key. + item := <-l.Items + if item.Typ == itemArgName { + p.Key = item.Val + + } else if item.Typ == itemRightRound { + break + + } else { + return result, fmt.Errorf("Expecting argument name. Got: %v", item) + } + + // Get value. + item = <-l.Items + if item.Typ == itemArgVal { + p.Val = item.Val + } else { + return result, fmt.Errorf("Expecting argument value. Got: %v", item) + } + + result = append(result, p) + } + return result, nil +} + func getRoot(l *lex.Lexer) (gq *GraphQuery, rerr error) { item := <-l.Items if item.Typ != itemName { @@ -155,40 +190,24 @@ func getRoot(l *lex.Lexer) (gq *GraphQuery, rerr error) { var uid uint64 var xid string - for { - var key, val string - // Get key or close bracket - item = <-l.Items - if item.Typ == itemArgName { - key = item.Val - } else if item.Typ == itemRightRound { - break - } else { - return nil, fmt.Errorf("Expecting argument name. Got: %v", item) - } - - // Get corresponding value. - item = <-l.Items - if item.Typ == itemArgVal { - val = item.Val - } else { - return nil, fmt.Errorf("Expecting argument va Got: %v", item) - } - - if key == "_uid_" { - uid, rerr = strconv.ParseUint(val, 0, 64) + args, err := parseArguments(l) + if err != nil { + return nil, err + } + for _, p := range args { + if p.Key == "_uid_" { + uid, rerr = strconv.ParseUint(p.Val, 0, 64) if rerr != nil { return nil, rerr } - } else if key == "_xid_" { - xid = val + } else if p.Key == "_xid_" { + xid = p.Val + } else { - return nil, fmt.Errorf("Expecting _uid_ or _xid_. Got: %v", item) + return nil, fmt.Errorf("Expecting _uid_ or _xid_. Got: %+v", p) } } - if item.Typ != itemRightRound { - return nil, fmt.Errorf("Unexpected token. Got: %v", item) - } + gq = new(GraphQuery) gq.UID = uid gq.XID = xid @@ -220,7 +239,21 @@ func godeep(l *lex.Lexer, gq *GraphQuery) error { } else if item.Typ == itemLeftRound { // absorb all these, we don't use them right now. + /* + for { + var key, val string + item = <-l.Items + if item.Typ == itemArgName { + key = item.Val + } else if item.Typ == itemRightRound { + break + } else { + return nil, fmt.Errorf("Expecting argument name. Got: %v", item) + } + } + */ for ti := range l.Items { + fmt.Println(ti.String()) if ti.Typ == itemRightRound || ti.Typ == lex.ItemEOF { return nil } diff --git a/gql/parser_test.go b/gql/parser_test.go index af9fb109d843aadd95cce88293a30a75001adaa8..fb5d1c81a0ac63cbbed58ccb1adb452a793fee2e 100644 --- a/gql/parser_test.go +++ b/gql/parser_test.go @@ -77,6 +77,7 @@ func TestParse(t *testing.T) { func TestParseXid(t *testing.T) { // logrus.SetLevel(logrus.DebugLevel) + // TODO: Why does the query not have _xid_ attribute? query := ` query { user(_uid_: 0x11) { @@ -100,6 +101,35 @@ func TestParseXid(t *testing.T) { } } +/* +func TestParseFirst(t *testing.T) { + // logrus.SetLevel(logrus.DebugLevel) + query := ` + query { + user(_xid_: m.abcd) { + type.object.name + friends (first: 10) { + } + } + }` + gq, _, err := Parse(query) + if err != nil { + t.Error(err) + return + } + if gq == nil { + t.Error("subgraph is nil") + return + } + if len(gq.Children) != 1 { + t.Errorf("Expected 1 children. Got: %v", len(gq.Children)) + } + if err := checkAttr(gq.Children[0], "type.object.name"); err != nil { + t.Error(err) + } +} +*/ + func TestParse_error2(t *testing.T) { query := ` query {