mirror of https://github.com/pikami/cosmium.git
Added support for object selects
This commit is contained in:
parent
5d2b21dc46
commit
b780e8c228
|
@ -87,6 +87,16 @@ func Test_Documents(t *testing.T) {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("Should query VALUE object", func(t *testing.T) {
|
||||||
|
testCosmosQuery(t, collectionClient,
|
||||||
|
"SELECT VALUE { id: c.id, _pk: c.pk } FROM c",
|
||||||
|
[]interface{}{
|
||||||
|
map[string]interface{}{"id": "12345", "_pk": "123"},
|
||||||
|
map[string]interface{}{"id": "67890", "_pk": "456"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("Should query document with single WHERE condition", func(t *testing.T) {
|
t.Run("Should query document with single WHERE condition", func(t *testing.T) {
|
||||||
testCosmosQuery(t, collectionClient,
|
testCosmosQuery(t, collectionClient,
|
||||||
`select c.id
|
`select c.id
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -18,7 +18,7 @@ func makeSelectStmt(columns, table, whereClause interface{}) (parsers.SelectStmt
|
||||||
return selectStmt, nil
|
return selectStmt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeSelectItem(name interface{}, path interface{}, alias interface{}, selectItemType parsers.SelectItemType) (parsers.SelectItem, error) {
|
func makeSelectItem(name interface{}, path interface{}, selectItemType parsers.SelectItemType) (parsers.SelectItem, error) {
|
||||||
ps := path.([]interface{})
|
ps := path.([]interface{})
|
||||||
|
|
||||||
paths := make([]string, 1)
|
paths := make([]string, 1)
|
||||||
|
@ -27,12 +27,7 @@ func makeSelectItem(name interface{}, path interface{}, alias interface{}, selec
|
||||||
paths = append(paths, p.(string))
|
paths = append(paths, p.(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
selectItem := parsers.SelectItem{Path: paths, Type: selectItemType}
|
return parsers.SelectItem{Path: paths, Type: selectItemType}, nil
|
||||||
if aliasValue, ok := alias.(string); ok {
|
|
||||||
selectItem.Alias = aliasValue
|
|
||||||
}
|
|
||||||
|
|
||||||
return selectItem, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeColumnList(column interface{}, other_columns interface{}) ([]parsers.SelectItem, error) {
|
func makeColumnList(column interface{}, other_columns interface{}) ([]parsers.SelectItem, error) {
|
||||||
|
@ -49,17 +44,28 @@ func makeColumnList(column interface{}, other_columns interface{}) ([]parsers.Se
|
||||||
return columnList, nil
|
return columnList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeSelectArray(columns interface{}, asClause interface{}) (parsers.SelectItem, error) {
|
func makeSelectArray(columns interface{}) (parsers.SelectItem, error) {
|
||||||
selectItem := parsers.SelectItem{
|
return parsers.SelectItem{
|
||||||
SelectItems: columns.([]parsers.SelectItem),
|
SelectItems: columns.([]parsers.SelectItem),
|
||||||
Type: parsers.SelectItemTypeArray,
|
Type: parsers.SelectItemTypeArray,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeSelectObject(field interface{}, other_fields interface{}) (parsers.SelectItem, error) {
|
||||||
|
fieldsAsArray := other_fields.([]interface{})
|
||||||
|
fieldsList := make([]parsers.SelectItem, len(fieldsAsArray)+1)
|
||||||
|
fieldsList[0] = field.(parsers.SelectItem)
|
||||||
|
|
||||||
|
for i, v := range fieldsAsArray {
|
||||||
|
if col, ok := v.(parsers.SelectItem); ok {
|
||||||
|
fieldsList[i+1] = col
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if aliasValue, ok := asClause.(string); ok {
|
return parsers.SelectItem{
|
||||||
selectItem.Alias = aliasValue
|
SelectItems: fieldsList,
|
||||||
}
|
Type: parsers.SelectItemTypeObject,
|
||||||
|
}, nil
|
||||||
return selectItem, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func joinStrings(array []interface{}) string {
|
func joinStrings(array []interface{}) string {
|
||||||
|
@ -114,13 +120,30 @@ TableName <- key:Identifier {
|
||||||
return parsers.Table{Value: key.(string)}, nil
|
return parsers.Table{Value: key.(string)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectArray <- "[" ws columns:ColumnList ws "]" asClause:AsClause? {
|
SelectArray <- "[" ws columns:ColumnList ws "]" {
|
||||||
return makeSelectArray(columns, asClause)
|
return makeSelectArray(columns)
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectItem <- SelectArray / name:Identifier path:(DotFieldAccess / ArrayFieldAccess)*
|
SelectObject <- "{" ws field:SelectObjectField ws other_fields:(ws "," ws coll:SelectObjectField {return coll, nil })* ws "}" {
|
||||||
asClause:AsClause? {
|
return makeSelectObject(field, other_fields)
|
||||||
return makeSelectItem(name, path, asClause, parsers.SelectItemTypeField)
|
}
|
||||||
|
|
||||||
|
SelectObjectField <- name:Identifier ws ":" ws selectItem:SelectItem {
|
||||||
|
item := selectItem.(parsers.SelectItem)
|
||||||
|
item.Alias = name.(string)
|
||||||
|
return item, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectProperty <- name:Identifier path:(DotFieldAccess / ArrayFieldAccess)* {
|
||||||
|
return makeSelectItem(name, path, parsers.SelectItemTypeField)
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectItem <- selectItem:(SelectArray / SelectObject / SelectProperty) asClause:AsClause? {
|
||||||
|
item := selectItem.(parsers.SelectItem)
|
||||||
|
if aliasValue, ok := asClause.(string); ok {
|
||||||
|
item.Alias = aliasValue
|
||||||
|
}
|
||||||
|
return item, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
AsClause <- ws As ws alias:Identifier { return alias, nil }
|
AsClause <- ws As ws alias:Identifier { return alias, nil }
|
||||||
|
|
|
@ -85,6 +85,26 @@ func Test_Parse(t *testing.T) {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("Should parse SELECT object", func(t *testing.T) {
|
||||||
|
testQueryParse(
|
||||||
|
t,
|
||||||
|
`SELECT { id: c.id, _pk: c.pk } AS obj FROM c`,
|
||||||
|
parsers.SelectStmt{
|
||||||
|
SelectItems: []parsers.SelectItem{
|
||||||
|
{
|
||||||
|
Alias: "obj",
|
||||||
|
Type: parsers.SelectItemTypeObject,
|
||||||
|
SelectItems: []parsers.SelectItem{
|
||||||
|
{Alias: "id", Path: []string{"c", "id"}},
|
||||||
|
{Alias: "_pk", Path: []string{"c", "pk"}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Table: parsers.Table{Value: "c"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("Should parse SELECT with single WHERE condition", func(t *testing.T) {
|
t.Run("Should parse SELECT with single WHERE condition", func(t *testing.T) {
|
||||||
testQueryParse(
|
testQueryParse(
|
||||||
t,
|
t,
|
||||||
|
|
|
@ -92,6 +92,14 @@ func getFieldValue(field parsers.SelectItem, row RowType) interface{} {
|
||||||
return arrayValue
|
return arrayValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if field.Type == parsers.SelectItemTypeObject {
|
||||||
|
objectValue := make(map[string]interface{})
|
||||||
|
for _, selectItem := range field.SelectItems {
|
||||||
|
objectValue[selectItem.Alias] = getFieldValue(selectItem, row)
|
||||||
|
}
|
||||||
|
return objectValue
|
||||||
|
}
|
||||||
|
|
||||||
value := row
|
value := row
|
||||||
for _, pathSegment := range field.Path[1:] {
|
for _, pathSegment := range field.Path[1:] {
|
||||||
if nestedValue, ok := value.(map[string]interface{}); ok {
|
if nestedValue, ok := value.(map[string]interface{}); ok {
|
||||||
|
|
|
@ -86,6 +86,30 @@ func Test_Execute(t *testing.T) {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("Should parse SELECT object", func(t *testing.T) {
|
||||||
|
testQueryExecute(
|
||||||
|
t,
|
||||||
|
parsers.SelectStmt{
|
||||||
|
SelectItems: []parsers.SelectItem{
|
||||||
|
{
|
||||||
|
Alias: "obj",
|
||||||
|
Type: parsers.SelectItemTypeObject,
|
||||||
|
SelectItems: []parsers.SelectItem{
|
||||||
|
{Alias: "id", Path: []string{"c", "id"}},
|
||||||
|
{Alias: "_pk", Path: []string{"c", "pk"}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Table: parsers.Table{Value: "c"},
|
||||||
|
},
|
||||||
|
mockData,
|
||||||
|
[]memoryexecutor.RowType{
|
||||||
|
map[string]interface{}{"obj": map[string]interface{}{"id": "12345", "_pk": 123}},
|
||||||
|
map[string]interface{}{"obj": map[string]interface{}{"id": "67890", "_pk": 456}},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("Should execute SELECT with single WHERE condition", func(t *testing.T) {
|
t.Run("Should execute SELECT with single WHERE condition", func(t *testing.T) {
|
||||||
testQueryExecute(
|
testQueryExecute(
|
||||||
t,
|
t,
|
||||||
|
|
Loading…
Reference in New Issue