Pipelines

Variable manipulation

The string-eval step is used to do string based evaluations, which allows a variety of actions to be performed. These include numeric calculations and casting to different data types.

The format will feel familiar to those with database and/or JavaScript experience. The expression is a constant that can use placeholders for input parameters so they can be used in the expression.

An example use case may look like the following:

- id: string-eval
  condition: radius_km
  params:
    param:
      bind: radius_miles
    expression:
      const: 'FLOAT(radius_km)/1.6'

This example takes an input variable radius_km, evaluates the expression and then writes the output variable to the radius_miles parameter. This step has the condition associated that ensures it only runs if the radius_km input exists.

You can also write the output back to one of the input variables. You don’t need to create a new variable. This is useful for augmenting existing parameters in place.

Variables always begin as strings, so you need convert them using INT() or FLOAT() casting to use them in mathematical expressions.

Operators

The expression supports AND, OR and XOR operators as well as parentheses. The logic also supports the IF() function much like you would see in databases and/or Excel (see Conditional functions below).

String concatenation

Much like JavaScript, strings can be concatenated using the + symbol. For example:

- id: string-eval
  params:
    param:
      bind: concat_output
    expression:
      const: firstName + ' ' + lastName

The above function would take two inputs and concatenate them with a space in between. Interestingly the JOIN() function could also have been used here:

- id: string-eval
  params:
    param:
      bind: concat_output
    expression:
      const: JOIN([firstName, lastName], " ")

Join comes into it’s own once you are dynamically adding things into a list, such as filter expressions. The brackets around the variables indicate a list, of which the elements are joined.

This is very useful for combining filters which may or may not exist in the request. Take the below example, if the bathFilter and priceFilter are NULL and the bedsFilter = “beds = 3”, then the output filterExpr = “beds = 3”

- id: string-eval
  params:
    param:
      bind: filterExpr
    expression:
      const: JOIN([bedsFilter, bathFilter, priceFilter], " AND ")

Much like JavaScript, if you don’t convert strings, operators may not do what you are expecting, e.g. 5+6 = 56 if “5” and “6” are strings.

Functions

This step supports a range of functions that can be used in the expression. These functions fall into several groups:

Casting

Convert a string into different data types. This is common for numeric operations.

INT(item)

Int attempts to convert the item to an integer. If the type is a float it will be rounded to the nearest integer.

FLOAT(item)

Float attempts to convert the item into a float.

STRING(item)

String converts the item to a string.

BOOL()

Bool attempts to convert the item to a Boolean. A zero will convert to FALSE, other numeric values will convert to TRUE. The string versions of TRUE and FALSE will convert as expected.

Conditional

IF(bool, item_if_true, item_if_false)

This takes a bool value (which could be the result of an expression), and returns item_if_true OR item_if_false for true/false values respectively.

Arrays

As previously shown above you can create and join lists using the bracket notation, e.g. [a]+[b] produces a list [a, b]

String functions

String functions allow for strings to be transformed, joined, quoted, trimmed and more.

JOIN(elements, separator)

Join concatenates the elements of its first argument to create a single string. The separator string sep is placed between elements in the resulting string.

QUOTE(string)

Quote returns a double-quoted string literal representing string. The returned string uses escape sequences (\t, \n, \xFF, \u0100) for control characters and non-printable characters.

LENGTH(item)

Length returns the number of bytes if the item is a string, or the number of elements if the item is an array.

TRIM(string)

Trim returns a slice of the string with all leading and trailing Unicode code points representing whitespace.

LTRIM(string)

LTrim returns a slice of the string with all leading Unicode code points representing whitespace.

RTRIM(string)

RTrim returns a slice of the string with all trailing Unicode code points representing whitespace.

RIGHT(string, num_of_chars)

Right extracts a number of characters num_of_chars from string (starting from right)

LEFT(string, num_of_chars)

Left extracts a number of characters num_of_chars from string (starting from left)

UPPER(string)

Upper converts string to upper-case.

LOWER(string)

Lower converts a string to lower-case.

Numeric functions

As the name suggests, numeric functions can be used to perform numeric transforms on inbound parameters.

POWER(base, exponent)

Power takes a base number and raises it to the power of the exponent.

ABS(number)

Abs returns the absolute value of number.

EXP(number)

Exp returns e raised to the power of number. The constant e (2.718281...), is the base of natural logarithms.

CEIL(number)

Ceil returns the smallest integer value that is larger than or equal to number.

FLOOR(number)

Floor returns the largest integer value that is smaller than or equal to number.

SQRT(number)

Sqrt returns the square root of number.

LN(number)

Ln returns the natural logarithm of number.

For example, you may want to calculate the square root of an input parameter (string):

- id: string-eval
  condition: my_number
  params:
    param:
      bind: my_number
    expression:
      const: SQRT(FLOAT(my_number))

In the above example, the input my_number must exist for the step to execute. If it does, it is converted from a string to a float, then the square root is calculated and written back into the variable. It could also go into a new parameter, but in this case we are writing to the existing parameter.