-
Notifications
You must be signed in to change notification settings - Fork 32
FScirpt parsing
FScripParser is a parser that parses a string into a Predicate or Expression.
FScript is an Expression class(later to be refactor to both: predicate and expression, doc to be updated) and has a method f(Object o).
The two properties on FScript that can be set are query and prop.
prop has PropertyInfo type and can be provided at the FScriptParser creation. This property allows for easier access to the specified property, so you can refer to it as thisValue when constructing a query. Example:
fs.setProp(foam.nanos.auth.User.GROUP);
fs.setQuery("thisValue==\"foamGroup\"");
var user = new User();
user.setGroup("foamGroup");
fs.f(user); // output true
user.setGroup("someOtherGroup");
fs.f(user); // output falseNote, FScript internally creates FScriptParser and PStream to parse the query and evaluate the object, however you can directly use FScriptParser, Example:
var sps = new foam.lib.parse.StringPStream();
var parser = new foam.parse.FScriptParser(foam.nanos.auth.User.GROUP);
var px = new foam.lib.parse.ParserContextImpl();
sps.setString("thisValue==\"foamGroup\");
var pred = (foam.mlang.predicate.Predicate) parser.parse(sps,px).value());
pred.f(user); // output true
user.setGroup("someOtherGroup");
pred.f(user); // output false
userDAO.where(pred)// returns users with group = foamGroup
The syntax for query is discussed below.
Every symbol in FScript corresponds to either an MLang predicate or an expression.
Predicates: operations:
- key>number key greater than number. Parsed to Gt predicate.
- key<number key less than number. Parsed to Lt predicate.
- key>=number key greater than number. Parsed to Gte predicate.
- key>=number key greater than number. Parsed to Lte predicate.
- key==value key equals value. Parsed to Eq predicate.
- key!=value key equals value. Parsed to Neq predicate.
- key~regexPattern key matches regexPattern. Parsed to RegExp predicate.
- key exists key key has a value set. Parsed to Has predicate.
- key isValid key is valid. Usually applied to Property of FObjectProperty type that internally define their own validation. Parsed to IsValid predicate.
All operations can be combined by using AND(&&)/OR(||) logical operator or parenthesis as well as be negated with the ! sign.
Parenthesis get priority over AND operator and And operator gets priority over OR operator.
Example:
query = (userName=="kristina"||birthday>2000/12/2)&&emailVerified==true&&!(group=="test"||userName~/a-z/)
All operations have expressions on both sides of the symbol.
Here is the list of possible expressions (no quotes unless specified):
-
number. Any number in the possible range of java/js
-
string. String must be double quoted.
-
true/false/null. Just say true/false/null
-
date. A date can be specified and be parsed into Constant expression. Date formats are:
-
year/month/dayThours:minutes
-
year/month/dayThours
-
year/month/day
-
year/month
-
year-month-dayThours:minutes
-
year-month-dayThours
-
year-month-day
-
year-month
-
-
regex. A regex must be specified in between
/signs. Example: /[a-z]/ -
field. Any field of the object that is to be evaluated. There is no type checking so it is the developer's responsibility to make sure that field has matching type with the other side of operation(if a predicate to be constructed). The field can be nested, for example, if evaluated object has properties of FObjectProperty type, dot(
.) can be used to refer to deeper level properties.Example: user.address.regionId=="ON" -
field length. String fields can be used to extract its length by appending
.len.Example: user.address.regionId.len<8 -
enum. Enums must have full path to the enum class itself as well as the name of the Enum value(name or label).
Example: status==foam.nanos.dao.Operation.CREATEorExample: status==foam.nanos.dao.Operation.Create -
formula. Formula lets you use arithmetic operations with expressions of number type. Possible operations are:
+,-,*,/. Examples:5==5region.len==5+10age*10>100years*daysInYear==100*299myAge-10>yourAge/3
Another control over the query execution is provided by if_else support. A predicate condition can be specified along with two expressions, that would be executed depending on the output of the predicate. Example:
if ( address.regionId.len==5 ) { firstName } else { lastName.len+3 }
- FScript is used internally in property validation predicates. So when a validation for property is specified in the following format:
validationPredicates: [
{
args: ['firstName'],
query: 'firstName.len>0',
errorString: 'Please enter first name'
}
]
the query string is the string that later on is set for FScript parsing so it uses the syntax discussed above.
Anywhere where predicates are used(right now under construction, the doc to be updated)
- FScript can also be used in Rule's predicates:
"predicate": {
"class": "foam.mlang.predicate.FScript",
"query":"user.group!=\"admin\""
}
Note that due to the nature of Rule's design, FScript and Predicates cannot be combined together.
- DAO queries:
var fs = new FScript("foam.nanos.auth.User.BIRTHDAY);
fs.setQuery("thisValue>1900/12/12");
userDAO.where(fs)