mirror of
https://github.com/dolthub/dolt.git
synced 2026-02-10 18:49:02 -06:00
GraphQL map set at (#3229)
Add support for at arguments to Map and Set elements Towards #3227
This commit is contained in:
@@ -9,16 +9,18 @@ import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
"github.com/attic-labs/noms/go/d"
|
||||
"github.com/attic-labs/noms/go/types"
|
||||
"github.com/attic-labs/graphql"
|
||||
"github.com/attic-labs/graphql/gqlerrors"
|
||||
"github.com/attic-labs/noms/go/d"
|
||||
"github.com/attic-labs/noms/go/types"
|
||||
)
|
||||
|
||||
const (
|
||||
atKey = "at"
|
||||
countKey = "count"
|
||||
elementsKey = "elements"
|
||||
keyKey = "key"
|
||||
rootKey = "root"
|
||||
rootQueryKey = "Root"
|
||||
scalarValue = "scalarValue"
|
||||
sizeKey = "size"
|
||||
@@ -26,8 +28,6 @@ const (
|
||||
targetValueKey = "targetValue"
|
||||
tmKey = "tm"
|
||||
valueKey = "value"
|
||||
rootKey = "root"
|
||||
elementsKey = "elements"
|
||||
vrKey = "vr"
|
||||
)
|
||||
|
||||
|
||||
@@ -104,6 +104,12 @@ func (suite *QueryGraphQLSuite) TestListBasic() {
|
||||
|
||||
suite.assertQueryResult(list, "{root{elements}}", `{"data":{"root":{"elements":[1,1.1,-100]}}}`)
|
||||
suite.assertQueryResult(list, "{root{elements(at:1,count:2)}}", `{"data":{"root":{"elements":[1.1,-100]}}}`)
|
||||
|
||||
list = types.NewList(types.String("a"), types.String("b"), types.String("c"))
|
||||
suite.assertQueryResult(list, "{root{elements(at:4)}}", `{"data":{"root":{"elements":[]}}}`)
|
||||
suite.assertQueryResult(list, "{root{elements(count:0)}}", `{"data":{"root":{"elements":[]}}}`)
|
||||
suite.assertQueryResult(list, "{root{elements(count:10)}}", `{"data":{"root":{"elements":["a","b","c"]}}}`)
|
||||
suite.assertQueryResult(list, "{root{elements(at:-1)}}", `{"data":{"root":{"elements":["a","b","c"]}}}`)
|
||||
}
|
||||
|
||||
func (suite *QueryGraphQLSuite) TestListOfStruct() {
|
||||
@@ -147,6 +153,18 @@ func (suite *QueryGraphQLSuite) TestSetBasic() {
|
||||
|
||||
suite.assertQueryResult(set, "{root{elements}}", `{"data":{"root":{"elements":[-100,1,1.1]}}}`)
|
||||
suite.assertQueryResult(set, "{root{elements(count:2)}}", `{"data":{"root":{"elements":[-100,1]}}}`)
|
||||
|
||||
set = types.NewSet(types.String("a"), types.String("b"), types.String("c"), types.String("d"))
|
||||
suite.assertQueryResult(set, "{root{elements(count:0)}}", `{"data":{"root":{"elements":[]}}}`)
|
||||
suite.assertQueryResult(set, "{root{elements(count:2)}}", `{"data":{"root":{"elements":["a","b"]}}}`)
|
||||
|
||||
suite.assertQueryResult(set, "{root{elements(at:0,count:2)}}", `{"data":{"root":{"elements":["a","b"]}}}`)
|
||||
suite.assertQueryResult(set, "{root{elements(at:-1,count:2)}}", `{"data":{"root":{"elements":["a","b"]}}}`)
|
||||
suite.assertQueryResult(set, "{root{elements(at:1,count:2)}}", `{"data":{"root":{"elements":["b","c"]}}}`)
|
||||
suite.assertQueryResult(set, "{root{elements(at:2)}}", `{"data":{"root":{"elements":["c","d"]}}}`)
|
||||
suite.assertQueryResult(set, "{root{elements(at:2,count:1)}}", `{"data":{"root":{"elements":["c"]}}}`)
|
||||
suite.assertQueryResult(set, "{root{elements(at:2,count:0)}}", `{"data":{"root":{"elements":[]}}}`)
|
||||
suite.assertQueryResult(set, "{root{elements(at:2,count:10)}}", `{"data":{"root":{"elements":["c","d"]}}}`)
|
||||
}
|
||||
|
||||
func (suite *QueryGraphQLSuite) TestSetOfStruct() {
|
||||
@@ -175,15 +193,29 @@ func (suite *QueryGraphQLSuite) TestMapBasic() {
|
||||
suite.assertQueryResult(m, "{root{elements}}", `{"data":{"root":{}}}`)
|
||||
|
||||
m = types.NewMap(
|
||||
types.String("foo"), types.Number(1),
|
||||
types.String("bar"), types.Number(2),
|
||||
types.String("baz"), types.Number(3),
|
||||
types.String("a"), types.Number(1),
|
||||
types.String("b"), types.Number(2),
|
||||
types.String("c"), types.Number(3),
|
||||
types.String("d"), types.Number(4),
|
||||
)
|
||||
|
||||
suite.assertQueryResult(m, "{root{elements{key value}}}", `{"data":{"root":{"elements":[{"key":"bar","value":2},{"key":"baz","value":3},{"key":"foo","value":1}]}}}`)
|
||||
suite.assertQueryResult(m, "{root{size}}", `{"data":{"root":{"size":3}}}`)
|
||||
suite.assertQueryResult(m, "{root{elements(count:2){value}}}", `{"data":{"root":{"elements":[{"value":2},{"value":3}]}}}`)
|
||||
suite.assertQueryResult(m, "{root{elements(count:3){key}}}", `{"data":{"root":{"elements":[{"key":"bar"},{"key":"baz"},{"key":"foo"}]}}}`)
|
||||
suite.assertQueryResult(m, "{root{elements{key value}}}", `{"data":{"root":{"elements":[{"key":"a","value":1},{"key":"b","value":2},{"key":"c","value":3},{"key":"d","value":4}]}}}`)
|
||||
suite.assertQueryResult(m, "{root{size}}", `{"data":{"root":{"size":4}}}`)
|
||||
|
||||
suite.assertQueryResult(m, "{root{elements(count:0){value}}}", `{"data":{"root":{"elements":[]}}}`)
|
||||
suite.assertQueryResult(m, "{root{elements(count:2){value}}}", `{"data":{"root":{"elements":[{"value":1},{"value":2}]}}}`)
|
||||
suite.assertQueryResult(m, "{root{elements(count:3){key}}}", `{"data":{"root":{"elements":[{"key":"a"},{"key":"b"},{"key":"c"}]}}}`)
|
||||
suite.assertQueryResult(m, "{root{elements(count: -1){key}}}", `{"data":{"root":{"elements":[]}}}`)
|
||||
suite.assertQueryResult(m, "{root{elements(count:5){value}}}", `{"data":{"root":{"elements":[{"value":1},{"value":2},{"value":3},{"value":4}]}}}`)
|
||||
|
||||
suite.assertQueryResult(m, "{root{elements(at:-1,count:2){value}}}", `{"data":{"root":{"elements":[{"value":1},{"value":2}]}}}`)
|
||||
suite.assertQueryResult(m, "{root{elements(at:0,count:2){value}}}", `{"data":{"root":{"elements":[{"value":1},{"value":2}]}}}`)
|
||||
suite.assertQueryResult(m, "{root{elements(at:1,count:2){value}}}", `{"data":{"root":{"elements":[{"value":2},{"value":3}]}}}`)
|
||||
suite.assertQueryResult(m, "{root{elements(at:2){value}}}", `{"data":{"root":{"elements":[{"value":3},{"value":4}]}}}`)
|
||||
suite.assertQueryResult(m, "{root{elements(at:2,count:1){value}}}", `{"data":{"root":{"elements":[{"value":3}]}}}`)
|
||||
suite.assertQueryResult(m, "{root{elements(at:2,count:0){value}}}", `{"data":{"root":{"elements":[]}}}`)
|
||||
suite.assertQueryResult(m, "{root{elements(at:5){value}}}", `{"data":{"root":{"elements":[]}}}`)
|
||||
suite.assertQueryResult(m, "{root{elements(at:2,count:10){value}}}", `{"data":{"root":{"elements":[{"value":3},{"value":4}]}}}`)
|
||||
}
|
||||
|
||||
func (suite *QueryGraphQLSuite) TestMapOfStruct() {
|
||||
|
||||
@@ -10,10 +10,10 @@ import (
|
||||
|
||||
"strings"
|
||||
|
||||
"github.com/attic-labs/graphql"
|
||||
"github.com/attic-labs/noms/go/d"
|
||||
"github.com/attic-labs/noms/go/hash"
|
||||
"github.com/attic-labs/noms/go/types"
|
||||
"github.com/attic-labs/graphql"
|
||||
)
|
||||
|
||||
type typeMap map[typeMapKey]graphql.Type
|
||||
@@ -222,29 +222,35 @@ var listArgs = graphql.FieldConfigArgument{
|
||||
countKey: &graphql.ArgumentConfig{Type: graphql.Int},
|
||||
}
|
||||
|
||||
func getListValues(v types.Value, args map[string]interface{}) (interface{}, error) {
|
||||
l := v.(types.List)
|
||||
idx := uint64(0)
|
||||
count := l.Len()
|
||||
func getBounds(l uint64, args map[string]interface{}) (uint64, uint64, bool) {
|
||||
len := int64(l)
|
||||
idx := int64(0)
|
||||
count := int64(len)
|
||||
if at, ok := args[atKey].(int); ok {
|
||||
idx = uint64(at)
|
||||
idx = int64(at)
|
||||
}
|
||||
if c, ok := args[countKey].(int); ok {
|
||||
count = uint64(c)
|
||||
count = int64(c)
|
||||
}
|
||||
|
||||
// Clamp ranges
|
||||
if count <= 0 || idx >= len {
|
||||
return 0, 0, true
|
||||
}
|
||||
if idx < 0 {
|
||||
idx = 0
|
||||
}
|
||||
if idx > l.Len() {
|
||||
idx = l.Len()
|
||||
if idx+count > len {
|
||||
count = len - idx
|
||||
}
|
||||
if count < 0 {
|
||||
count = 0
|
||||
}
|
||||
if idx+count > l.Len() {
|
||||
count = l.Len() - idx
|
||||
return uint64(idx), uint64(count), false
|
||||
}
|
||||
|
||||
func getListValues(v types.Value, args map[string]interface{}) (interface{}, error) {
|
||||
l := v.(types.List)
|
||||
idx, count, empty := getBounds(l.Len(), args)
|
||||
if empty {
|
||||
return ([]interface{})(nil), nil
|
||||
}
|
||||
|
||||
values := make([]interface{}, count)
|
||||
@@ -257,63 +263,46 @@ func getListValues(v types.Value, args map[string]interface{}) (interface{}, err
|
||||
}
|
||||
|
||||
var setArgs = graphql.FieldConfigArgument{
|
||||
atKey: &graphql.ArgumentConfig{Type: graphql.Int},
|
||||
countKey: &graphql.ArgumentConfig{Type: graphql.Int},
|
||||
}
|
||||
|
||||
func getSetValues(v types.Value, args map[string]interface{}) (interface{}, error) {
|
||||
// TODO: Refactor to share code between the collections.
|
||||
s := v.(types.Set)
|
||||
|
||||
count := s.Len()
|
||||
if c, ok := args[countKey].(int); ok {
|
||||
count = uint64(c)
|
||||
}
|
||||
|
||||
// Clamp ranges
|
||||
if count < 0 {
|
||||
count = 0
|
||||
}
|
||||
if count > s.Len() {
|
||||
count = s.Len()
|
||||
idx, count, empty := getBounds(s.Len(), args)
|
||||
if empty {
|
||||
return ([]interface{})(nil), nil
|
||||
}
|
||||
|
||||
values := make([]interface{}, count)
|
||||
i := uint64(0)
|
||||
s.Iter(func(v types.Value) bool {
|
||||
values[i] = maybeGetScalar(v)
|
||||
i++
|
||||
return i >= count
|
||||
})
|
||||
iter := s.IteratorAt(idx)
|
||||
for i := uint64(0); i < count; i++ {
|
||||
values[i] = maybeGetScalar(iter.Next())
|
||||
}
|
||||
|
||||
return values, nil
|
||||
}
|
||||
|
||||
var mapArgs = graphql.FieldConfigArgument{
|
||||
atKey: &graphql.ArgumentConfig{Type: graphql.Int},
|
||||
countKey: &graphql.ArgumentConfig{Type: graphql.Int},
|
||||
}
|
||||
|
||||
func getMapValues(v types.Value, args map[string]interface{}) (interface{}, error) {
|
||||
// TODO: Refactor to share code between the collections.
|
||||
m := v.(types.Map)
|
||||
|
||||
count := m.Len()
|
||||
if c, ok := args[countKey].(int); ok {
|
||||
count = uint64(c)
|
||||
}
|
||||
|
||||
// Clamp ranges
|
||||
if count < 0 {
|
||||
count = 0
|
||||
}
|
||||
if count > m.Len() {
|
||||
count = m.Len()
|
||||
idx, count, empty := getBounds(m.Len(), args)
|
||||
if empty {
|
||||
return ([]interface{})(nil), nil
|
||||
}
|
||||
|
||||
values := make([]mapEntry, count)
|
||||
i := uint64(0)
|
||||
m.Iter(func(k, v types.Value) bool {
|
||||
iter := m.IteratorAt(idx)
|
||||
for i := uint64(0); i < count; i++ {
|
||||
k, v := iter.Next()
|
||||
values[i] = mapEntry{k, v}
|
||||
i++
|
||||
return i >= count
|
||||
})
|
||||
}
|
||||
|
||||
return values, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user