Skip to content

Instantly share code, notes, and snippets.

@sdesai
Created June 29, 2012 22:38
Show Gist options
  • Save sdesai/3021149 to your computer and use it in GitHub Desktop.
Save sdesai/3021149 to your computer and use it in GitHub Desktop.
Simple Query Syntax To Try and Normalize SQL/noSQL selection criteria

EXPRESSIONS

  1. key : primitive ({name:"foobar"})

  2. key : regex ({name:/^foo.*?/"})

  3. key : { condition : primitive } ({age: {gt: 21}})

  4. key : function(key, val) { returns true/false } (would need to be post-process?)

  5. key : condition(val) ({a:gt(10)})

    • Occurred to me this might be better than 3. above.

    • Looks nicer/More Flexible/Customizable

    • Would be like returning a prepackaged string with key, val replaced

    • Not thunk through all the way, but thinking while toSQL()'ing the query object, it would insert the key into the function returned by gt(val), which would be something like

         e.g. gt = function(val) { return function(key) { return key + " GT " + val; } }
      

LOGICAL OPERATORS

  1. keys in an object imply "AND"
  2. entries in an array imply "OR"
  3. For complex AND/OR grouping you can use the .and(queryexpression) and .or(queryexpression) calls, as shown below.

EXAMPLE 1 (ALL ANDS)

a = 10 && (b > 2 && b < 10) && c !== null

    myQuery = query({
      a: 10,
      b: {
         gt: 2,
         lt: 10
      },
      c: {
         ne:null // or, exists:true?
      }
    })

The db.getObjects() method would call this to transform to SQL, if on a SQL DB:

    myQuery.toSQL()

EXAMPLE 2 (ALL ORs)

a = 2 || b = 3

    query([
       {a:2},
       {b:3}
    ])

Equivalent to:

    query({a:2}).or({b:3})

EXAMPLE 3 (SIMPLE ORs/ANDs)

(a = 2 || a = 3) && b = 3

    query({
       a : [2, 3],
       b : 3
    })

Equivalent to:

    query({a:2}).or({a:3}).and({b:3})

EXAMPLE 4 (COMPLEX ORs/ANDs GROUPING)

(c = 4) && ((a > 4 && a < 10) || (b = 5))

    query({c:4}).and(
       query({a:{gt:4, lt:10}}).or({b:5})
    )

USAGE

   db.getObjects(myTable, columnsToSelectArray, myQuery, success, failure)

I'm not sure about columnsToSelectArray - does it make sense for noSQL DBs

CONCLUSION

Seems like this gets us a simple to use literal/declarative form for the common use cases, while letting us move to a programmatic API for the immediate complex use cases, plus future ones, without having to create complex constructs in order to support everything in the declarative form.

Seems like this is the thing to start implementing against.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment