Skip to content

Commit

Permalink
make column check a function instead of map
Browse files Browse the repository at this point in the history
  • Loading branch information
yaacov committed Dec 3, 2018
1 parent 66cde18 commit ec558ea
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 20 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ where part. implementing query based search engines was never that easy.

The TSL language grammar is similar to SQL syntax.

## Code examples

For complete working code examples see the cli tools direcotry in the [/cmd](/cmd).

## Syntax examples

#### Operator precedence
Expand Down
27 changes: 21 additions & 6 deletions cmd/tsl_sqlite/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,26 @@ func check(err error) {
}
}

// columnNamesMap mapps between user namespace and the SQL column names.
var columnNamesMap = map[string]string{
"title": "title",
"author": "author",
"spec.pages": "pages",
"spec.rating": "rating",
}

// checkColumnName checks if a coulumn name is valid in user space replace it
// with the mapped column name and returns and error if not a valid name.
func checkColumnName(s string) (string, error) {
// Chekc for column name in map.
if v, ok := columnNamesMap[s]; ok {
return v, nil
}

// If not found return string as is, and an error.
return s, fmt.Errorf("column \"%s\" not found", s)
}

func main() {
var bookID uint
var rows *sql.Rows
Expand Down Expand Up @@ -68,12 +88,7 @@ func main() {
check(err)

// Check and replace user identifiers with the SQL table column names.
tree, err = ident.Walk(tree, map[string]string{
"title": "title",
"author": "author",
"spec.pages": "pages",
"spec.rating": "rating",
})
tree, err = ident.Walk(tree, checkColumnName)
check(err)

// Prepare SQL filter.
Expand Down
38 changes: 24 additions & 14 deletions pkg/walkers/ident/walk.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
package ident

import (
"fmt"

"github.com/yaacov/tsl/pkg/tsl"
)

Expand All @@ -27,41 +25,53 @@ import (
// Users can call the Walk method to check and replace identifiers.
//
// Example:
// columnNamesMap := map[string]string{
// "title": "title",
// "author": "author",
// "spec.pages": "pages",
// "spec.rating": "rating",
// }
//
// func check(s string) (string, error) {
// // Chekc for column name in map.
// if v, ok := columnNamesMap[s]; ok {
// return v, nil
// }
//
// // Check and replace user identifiers with the SQL table column names.
// // If not found return string as is, and an error.
// return s, fmt.Errorf("column not found")
// }
//
// // Check and replace user identifiers with the SQL table column names.
// //
// // SQL table columns are "title, author, pages and rating", but for
// // users pages and ratings are fields of an internal struct called
// // spec (e.g. {"title": "Book", "author": "Joe", "spec": {"pages": 5, "rating": 5}}).
// //
// newTree, err = ident.Walk(tree, map[string]string{
// "title": "title",
// "author": "author",
// "spec.pages": "pages",
// "spec.rating": "rating",
// })
// newTree, err = ident.Walk(tree, check)
//
func Walk(n tsl.Node, identMap map[string]string) (tsl.Node, error) {
func Walk(n tsl.Node, checkColumnName func(string) (string, error)) (tsl.Node, error) {
var err error
var v string

// Walk tree.
switch n.Func {
case tsl.IdentOp:
// If we have an identifier, check for it in the identMap.
if v, ok := identMap[n.Left.(string)]; ok {
if v, err = checkColumnName(n.Left.(string)); err == nil {
// If valid identifier, use it.
n.Left = v
return n, nil
}

return n, fmt.Errorf("unknown identifier: %s", n.Left.(string))
return n, err
case tsl.StringOp, tsl.NumberOp:
// This are our leafs.
return n, nil
default:
// Check identifiers on left side.
if n.Left != nil {
n.Left, err = Walk(n.Left.(tsl.Node), identMap)
n.Left, err = Walk(n.Left.(tsl.Node), checkColumnName)
if err != nil {
return n, err
}
Expand All @@ -75,7 +85,7 @@ func Walk(n tsl.Node, identMap map[string]string) (tsl.Node, error) {
// We assume that all are leafs, no nead to walk on them.
if _, ok := n.Right.(tsl.Node); ok {
// It's a node.
n.Right, err = Walk(n.Right.(tsl.Node), identMap)
n.Right, err = Walk(n.Right.(tsl.Node), checkColumnName)
if err != nil {
return n, err
}
Expand Down

0 comments on commit ec558ea

Please sign in to comment.