mirror of
https://github.com/pikami/cosmium.git
synced 2025-12-19 17:00:37 +00:00
Added support for 'ORDER BY'
This commit is contained in:
@@ -25,12 +25,20 @@ const (
|
||||
SelectItemTypeArray
|
||||
)
|
||||
|
||||
type OrderDirection int
|
||||
|
||||
const (
|
||||
OrderDirectionAsc OrderDirection = iota
|
||||
OrderDirectionDesc
|
||||
)
|
||||
|
||||
type SelectStmt struct {
|
||||
SelectItems []SelectItem
|
||||
Table Table
|
||||
Filters interface{}
|
||||
Count int
|
||||
Parameters map[string]interface{}
|
||||
SelectItems []SelectItem
|
||||
Table Table
|
||||
Filters interface{}
|
||||
Count int
|
||||
Parameters map[string]interface{}
|
||||
OrderExpressions []OrderExpression
|
||||
}
|
||||
|
||||
type Table struct {
|
||||
@@ -60,3 +68,8 @@ type Constant struct {
|
||||
Type ConstantType
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
type OrderExpression struct {
|
||||
SelectItem SelectItem
|
||||
Direction OrderDirection
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@ package nosql
|
||||
|
||||
import "github.com/pikami/cosmium/parsers"
|
||||
|
||||
func makeSelectStmt(columns, table, whereClause interface{}, count interface{}) (parsers.SelectStmt, error) {
|
||||
func makeSelectStmt(columns, table, whereClause interface{}, count interface{}, orderList interface{}) (parsers.SelectStmt, error) {
|
||||
selectStmt := parsers.SelectStmt{
|
||||
SelectItems: columns.([]parsers.SelectItem),
|
||||
Table: table.(parsers.Table),
|
||||
@@ -21,6 +21,10 @@ func makeSelectStmt(columns, table, whereClause interface{}, count interface{})
|
||||
selectStmt.Count = n
|
||||
}
|
||||
|
||||
if orderExpressions, ok := orderList.([]parsers.OrderExpression); ok {
|
||||
selectStmt.OrderExpressions = orderExpressions
|
||||
}
|
||||
|
||||
return selectStmt, nil
|
||||
}
|
||||
|
||||
@@ -74,6 +78,33 @@ func makeSelectObject(field interface{}, other_fields interface{}) (parsers.Sele
|
||||
}, nil
|
||||
}
|
||||
|
||||
func makeOrderByClause(ex1 interface{}, others interface{}) ([]parsers.OrderExpression, error) {
|
||||
othersArray := others.([]interface{})
|
||||
orderList := make([]parsers.OrderExpression, len(othersArray)+1)
|
||||
orderList[0] = ex1.(parsers.OrderExpression)
|
||||
|
||||
for i, v := range othersArray {
|
||||
if col, ok := v.(parsers.OrderExpression); ok {
|
||||
orderList[i+1] = col
|
||||
}
|
||||
}
|
||||
|
||||
return orderList, nil
|
||||
}
|
||||
|
||||
func makeOrderExpression(field interface{}, order interface{}) (parsers.OrderExpression, error) {
|
||||
value := parsers.OrderExpression{
|
||||
SelectItem: field.(parsers.SelectItem),
|
||||
Direction: parsers.OrderDirectionAsc,
|
||||
}
|
||||
|
||||
if orderValue, ok := order.(parsers.OrderDirection); ok {
|
||||
value.Direction = orderValue
|
||||
}
|
||||
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func joinStrings(array []interface{}) string {
|
||||
var stringsArray []string
|
||||
for _, elem := range array {
|
||||
@@ -106,8 +137,9 @@ Input <- selectStmt:SelectStmt {
|
||||
|
||||
SelectStmt <- Select ws topClause:TopClause? ws columns:Selection ws
|
||||
From ws table:TableName ws
|
||||
whereClause:(ws Where ws condition:Condition { return condition, nil })? {
|
||||
return makeSelectStmt(columns, table, whereClause, topClause)
|
||||
whereClause:(ws Where ws condition:Condition { return condition, nil })?
|
||||
orderByClause:OrderByClause? {
|
||||
return makeSelectStmt(columns, table, whereClause, topClause, orderByClause)
|
||||
}
|
||||
|
||||
TopClause <- Top ws count:Integer {
|
||||
@@ -193,6 +225,22 @@ ComparisonExpression <- "(" ws ex:OrExpression ws ")" { return ex, nil }
|
||||
return parsers.ComparisonExpression{Left:left,Right:right,Operation:string(op.([]uint8))}, nil
|
||||
} / ex:BooleanLiteral { return ex, nil }
|
||||
|
||||
OrderByClause <- OrderBy ws ex1:OrderExpression others:(ws "," ws ex:OrderExpression { return ex, nil })* {
|
||||
return makeOrderByClause(ex1, others)
|
||||
}
|
||||
|
||||
OrderExpression <- field:SelectProperty ws order:OrderDirection? {
|
||||
return makeOrderExpression(field, order)
|
||||
}
|
||||
|
||||
OrderDirection <- ("ASC" / "asc" / "DESC" / "desc") {
|
||||
switch string(c.text) {
|
||||
case "DESC", "desc":
|
||||
return parsers.OrderDirectionDesc, nil
|
||||
}
|
||||
return parsers.OrderDirectionAsc, nil
|
||||
}
|
||||
|
||||
Select <- ("select" / "SELECT")
|
||||
|
||||
Top <- ("top" / "TOP")
|
||||
@@ -207,6 +255,8 @@ And <- ("and" / "AND")
|
||||
|
||||
Or <- ("or" / "OR")
|
||||
|
||||
OrderBy <- ("order" / "ORDER") ws ("by" / "BY")
|
||||
|
||||
ComparisonOperator <- "=" / "!=" / "<" / "<=" / ">" / ">=" {
|
||||
return string(c.text), nil
|
||||
}
|
||||
|
||||
@@ -132,6 +132,30 @@ func Test_Parse(t *testing.T) {
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse SELECT with ORDER BY", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT c.id, c["pk"] FROM c ORDER BY c.id DESC, c.pk`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{Path: []string{"c", "id"}},
|
||||
{Path: []string{"c", "pk"}},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
OrderExpressions: []parsers.OrderExpression{
|
||||
{
|
||||
SelectItem: parsers.SelectItem{Path: []string{"c", "id"}},
|
||||
Direction: parsers.OrderDirectionDesc,
|
||||
},
|
||||
{
|
||||
SelectItem: parsers.SelectItem{Path: []string{"c", "pk"}},
|
||||
Direction: parsers.OrderDirectionAsc,
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse SELECT with single WHERE condition", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
|
||||
Reference in New Issue
Block a user