Coder Social home page Coder Social logo

go-rql-parser's Introduction

GO-RQL-PARSER

Build Status Coverage Status

Small, simple and lightweight library for Go web applications to translate RQL (Resource Query Language) queries to SQL

Usage

query := `and(eq(foo,3),lt(price,10))&sort(+price)`

p := rqlParser.NewParser() // Instanciate a new parser

// Parse the query and return the root node of the generated tree
rqlRootNode, err := p.Parse(query) 
if err != nil {
	panic("Query is not a valid rql : " + err.Error())
}

// Return the sql string for querying DB
sql, err := rqlParser.NewSqlTranslator(rqlNode).Sql()
if err != nil {
	panic(err)
}

fmt.Println(sql) 
// Print `WHERE ((foo=3) AND (price < 10)) ORDER BY price

Supported operators

The library support by default the following RQL operators :

  • AND
    • SQL Operator : AND
  • OR
    • SQL Operator : OR
  • NE
    • SQL Operator : != (When value is NULL it is translated to the IS NOT SQL operator)
  • EQ
    • SQL Operator : = (When value is NULL it is translated to the IS SQL operator)
  • LIKE
    • SQL Operator : LIKE
  • MATCH
    • SQL Operator : ILIKE
  • GT
    • SQL Operator : >
  • LT
    • SQL Operator : <
  • GE
    • SQL Operator : >=
  • LE
    • SQL Operator : <=
  • SUM
    • SQL Operator : SUM
  • NOT
    • SQL Operator : NOT

Append supported operators

It's easy to handle new operators by simply adding a TranslatorOpFunc to the SQLTranslator :

query := `or(eq(foo,42),between(price,10,100))`
rqlRootNode, err := p.Parse(query) 
if err != nil { 
  panic("Query is not a valid rql : " + err.Error()) 
}

sqlTranslator := rqlParser.NewSqlTranslator(rqlNode)

// Before translating the node, just add the custom operator
// let's define a new function to handle beetween operator
betweenTranslatorFunc := func(n *rqlParser.RqlNode) (s string, err error) {
	var (
		min, max int64
		field    string
	)

	if len(n.Args) != 3 {
		err = fmt.Errorf("between operator require 3 arguments")
		return
	}

	for i, a := range n.Args {
		if v, ok := a.(string); ok {
			switch i {
			case 0:
				if rqlParser.IsValidField(v) {
					field = v
				} else {
					return "", fmt.Errorf("First argument must be a valid field name (arg: %s)", v)
				}
			case 1, 2:
				num, err := strconv.ParseInt(v, 10, 64)
				if err != nil {
					return "", fmt.Errorf("Argument n°%d must be an integer (arg: %s)", i, v)
				}
				if i == 1 {
					min = num
				} else {
					max = num
				}
			}
		} else {
			err = fmt.Errorf("Between example function only support string arguments")
			return
		}
	}

	s = fmt.Sprintf("(%s >= %d) AND (%s <= %d)", field, min, field, max)

	return
}

sqlTranslator.SetOpFunc(`between`, rqlParser.TranslatorOpFunc(betweenTranslatorFunc))
s, err := sqlTranslator.Sql() 
if err != nil { 
  panic(err) 
}
fmt.Println(s) // Will print : "WHERE ((foo=42) OR ((price >= 10) AND (price <= 100)))"

Contributions

Any contribution is welcome.

There is still many improvements that should be added to this library :

  • Support type casting (ex: string:42 to force the SQLTranslator to handle 42 as a string)
  • Create a per database architecture translator as all databases doesn't support the same operators.

go-rql-parser's People

Contributors

tbaud0n avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

go-rql-parser's Issues

add table alias and quotes

where generator should be able to handle table alias, and/or should also quote column names.
WHERE ((t.\foo` = 3) AND (t.`price` < 10)) ORDER BY t.`price`
`

generate parameterized sql queries

Hi, I am always fascinated by projects like this. Every once in a while I am back to the point of playing with those kinds of libraries or trying to build my own.

I noticed that the output of the translator doesn't seem to be injection safe. Is it possible to get a parameterized query from it whith placeholders and a slice of values ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.