These are NOT the results you are looking for - OData parser

Published on 2013-4-16

A quick re-cap of where we are so far in our OData OMeta Adventure.

Before we get onto some more fuzzy stuff, it would be good to deal with 'not'

Not is an interesting case because it's not really the same as the rest of the expressions so far

Not  Logical negation  /Products?$filter=not endswith(Description,'milk')

It can't apply in situations like this however

/Products?$filter=not Product eq 5

But it can probably apply in situations like this

/Products?$filter=not Published

This tells us something, which is that not isn't going to be expecting an expression unless it's in braces, otherwise it's going to be looking for a value.

I'm not supporting methods yet, so I'll ignore that requirement for now.

test("/some/resource?$filterby=not Published", "OData", function(result) {

  it("A filter should be present", function() {
     assert.notEqual(result.options.$filterby, null)
  })
  it("Filter should be an instance of 'not'", function() {
     assert.equal(result.options.$filterby[0], "not")
  })

  it("value should be 'Published'", function() {
    assert.equal(result.options.$filterby[1].name, "Published")
  })
})

First off, this one

FilterByValue = 
  FilterNegateExpression
|  Number
| QuotedText
| PropertyPath
,

FilterNegateExpression = 
  spaces
  seq("not")
  spaces
  FilterByValue:value       ->  [ "not", value ]
,

Quite simple, if we get as far as checking for a value, it means we haven't found an expression, so we'll check for "Not" - I guess this is where we'll probably stick methods later too.

A "NegateExpression" is simply a "not" followed by a value, we'll allow double negatives too because there is no harm in this.

Next up, we'll check for braces, and inside braces we'll allow further expressions (recurse recurse recurse)

test("/some/resource?$filterby=not (Price gt 5)", "OData", function(result) {

  it("A filter should be present", function() {
     assert.notEqual(result.options.$filterby, null)
  })
  it("Filter should be an instance of 'not'", function() {
     assert.equal(result.options.$filterby[0], "not")
  })
  it("Value should be Price gt 5", function() {
     var rhs = result.options.$filterby[1] 
     assert.equal(rhs[0], "gt")
     assert.equal(rhs[1].name, "Price")
     assert.equal(rhs[2], 5)
  })
})

Solved by

FilterNegateExpression = 
  spaces
  seq("not")
  spaces
  (
    FilterByValue
  | '(' spaces FilterByExpression:expr spaces ')' -> expr
  ):value ->  [ "not", value ]
,

Dead easy, now it's time to get our heads stuck into Arithmetic Operators.

2020 © Rob Ashton. ALL Rights Reserved.