The logicContext Object

The logicContext Object
lac40
Logic context makes visible key aspects of logic execution. You can use the 
logicContext
 object in your JavaScript rules. This object provides access to runtime services, to runtime state, and to services to create, read, update, and delete rows.
For more information about logic execution, see Logic Execution.
 
Limitation:
 You cannot use the 
logicContext
 object in rules that are tied to non-persistent attributes or JIT (just-it-time) compilation.
In this article:
 
3
verb Property
The 
verb
 property defines what the current logic iteration is trying to do (INSERT, UPDATE, or DELETE).
 
Example:
 
if (logicContext.verb == 'UPDATE')
log.debug('We are updating');
The 
verb
 property is distinct from the 
initialVerb
 property. A rule might have kicked of the current logic iteration. For instance, Item logic might update an inserted row (such as Order) later in the transaction. For the Order, the verb is 
INSERT
 initially, then 
UPDATE
 as the Items are processed. The 
initialVerb
 property remains INSERT.
For more information about the 
initialVerb
 property, see the "initialVerb Property" section.
initialVerb Property
The 
initialVerb
 property indicates the verb that is initially executed on a row.
 
Example:
 
if (logicContext.
initialVerb
== 'INSERT') log.debug('This started as an Insert transaction');
Consider inserting an Order and several Items. The item logic updates the Order, but the Order can determine that it was initially inserted in this transaction. For example, can bypass auditing logic when an Order is inserted.
logicNestLevel Method
This property is for advanced users
The 
logicNestLevel
 property indicates the depth of the nesting.
 
Prerequisite:
 You understand complex nested logic.
 
Example:
 
if (logicContext.
logicNestLevel
> 0) // Do something only at the top level of nesting
return;
setUseCaseName Method
You can make debugging easier by creating rule that sets the 
setUseCaseName()
 method. The given name appears in the logs, which can be helpful in understanding the flow of a transaction.
 
Example:
 
logicContext.
setUseCaseName
('Insert log record');
setUserProperty Method
The 
setUserProperty()
 method sets user properties during the transaction. When the transaction ends, the user properties disappear. The next transaction, even for the same API key, does not see these values. The value of a user property can be anything.
 
Example:
 
logicContext.
setUserProperty
('myFlag', true);if (logicContext.getUserProperty('myFlag) log.debug('myFlag is true');
 The 
setUserProperty()
 method can introduce some subtle and non-obvious dependencies between rules. Nevertheless, they can be useful sometimes.
logDebug Method
You can output messages to the log by creating a rule that sets the 
logDebug
 method. You can update objects. The 
logDebug
 method is distinct from the 
queryDatabase
 method.
 
Example:
 
The following code snippet outputs the given message to the transaction's log, using the Debugger:
log.debug('Customer balance is: ' + currentObject.balance); logicContext.
logDebug
('Customer balance is: ' + currentObject.balance);
 You cannot use the 
logicContext.logDebug()
 method (and other methods) in formulas that non-persistent attributes use. Instead, use the 
log
 object's 
debug()
 method. The other variations of this method, 
logFiner
 and 
logFinest
, use a lower level of logging.
For more information about the 
debug()
 method, see The log Object.
createPersistentBean Method
You can create a new object, ready to be inserted, using the 
createPersistentBean()
 method.
 
Example:
 
var newCustomer = logicContext.
createPersistentBean
("Customer");
newCustomer.name = 'My new customer';
logicContext.insert(newCustomer);
getBeanByPrimaryKey Method
You can retrieve an existing object by its primary key with the 
getBeanByPrimaryKey()
 method.
 
Example:
 
var customer = logicContext.getBeanByPrimaryKey("Customer", "123");
The second argument must be a string. The argument is converted to the proper type as needed. If the primary key for the given table is a composite key, separate the values by a tilde (~) in the database order, with double-tilde (~~) to quote the tilde itself:
var order = logicContext.
getBeanByPrimaryKey
("MyTable", "456~abc");
The 
getBeanByPrimaryKey()
 method expects to find a valid record. If a row is not found, it does not return a null row. To determine whether a row actually exists, use:
var customer = logicContext.getBeanByUniqueAttributes("demo:customer", ["id"], [123]);
where the arguments are:
  • The 
    Object
     Name.
  • The 
    Attributes
     you are selecting against.
  • The 
    Values
     used for the query.
This code snippet returns single bean if found, null if not found, or throws an exception if not unique.
getRowsByQuery Method
You can retrieve a set of objects using a SQL where clause with the 
getRowsByQuery()
 method.
 
Example:
 
var rows = logicContext.
getRowsByQuery
("product",
"select * from product where name <> 'Drill'");
for (var i = 0; i < rows.length; i++)
log.debug('Found product:' + rows[i].name);
insertChildrenFrom Method
You can access related parent/child data by way of their relationships using the 
insertChildrenFrom()
 method. Consider the following code snippet from the Bill of Materials Kit Explosion example. The Bill Of Materials Kit Explosion example is an advanced example. The requirement is to populate the subitems for a kit-based 
Lineitem
 (see the database structure) by copying the 
ProductBillofMaterials
 to the subItems. You can do this with the following 
explodeBillofMaterials
 event rule on 
Lineitem
:
if (logicContext.verb == "INSERT" && row.product.count_components > 0) {
SysLogic.insertChildrenFrom("lineitems", row.product.components, logicContext);
}
In this example 
row.product.count_components
 uses a parent accessor. Given a line item, it accesses the related product and returns the value of the 
count_components
 attribute. 
row.product.components
 is a child accessor. It accesses the list of components for a line item's product.
The remaining logic (four rules) is to arrange for quantities properly (that is, if you buy two planes, you need eight engines).
For more information:
insert Method
You can insert a new object (presumably created with the 
createPersistentBean
 method) using the 
insert()
 method; see 
createPersistentBean
 for an example:
var newPurchaseorder_audit = logicContext.createPersistentBean("purchaseorder_audit");
newPurchaseorder_audit.amount_total = oldRow.amount_total; // set attributes from old values
newPurchaseorder_audit.paid = oldRow.paid;
newPurchaseorder_audit.customer_name = oldRow.customer_name;
newPurchaseorder_audit.order_number = oldRow.order_number; // set the foreign key
logicContext.insert(newPurchaseorder_audit);
touch Method
You can update an object in an action.
  1. Call the 
    touch()
     method.
     The 
    touch()
     method is required to set up the old values, is required for 
    oldRow
     , and is required for optimistic locking. This requirement applies only to objects that you retrieve on your own. You must invoke this method in the following circumstances:
    • If you read a row and then want to update/delete it.For more information about an example, see the "Insert an Object" example.
    • In an event, if you change the row and need to update it again to re-run the rules on changes to the row made in the event.
  2. Change any column in the row.
  3. Call the 
    update
     method.
 
Example:
 
The following code snippet updates an object, calling the 
touch()
 method and the 
update()
 method:
var customer = logicContext.
getBeanByPrimaryKey
("customer", "123");
logicContext.
touch
(customer); // IMPORTANT!
customer.name = 'Updated customer';
logicContext.
update
(customer);
delete Method
You can delete an object with the 
delete
 method:
var customer = logicContext.
getBeanByPrimaryKey
("customer", "123"); logicContext.
delete
(customer);
queryDatabase Method
You can issue an arbitrary SQL query, within the context of the transaction, using the 
queryDatabase()
 method. You can use JDBC 
?
 syntax for parameterized queries:
// Use this to query the database and log the results (for example) to the API Creator Logs
var result = SysLogic.
queryDatabase
('demo', 'select * from customer where balance > ?', [10]);
for (var i = 0; i < result.length; ++i) {
var s = '';
for (var id in result[i]) {
s += ', ' + id + '=' + result[i][id];
}
log.debug(s);
}
transformCurrentRow Method
The 
logicContext
 object's
transformCurrentRow()
method transforms a table row to a resource instance as a JSON string. This method is typically called in a table event. This method provides transformation logic to select/rename attributes and related objects.
 For more information:
rowToJSON Method
You can convert a row to a JSON structure with appropriate datatypes that can be passed to other persistent document storage systems, for example:
log.debug("JSON for object is : " + logicContext.
rowToJSON
(row));
The following response is expected:
{
"location_ident": 1,
"amount": 1.06,
"budget_date": null,
"ident": 9,
"city_ident": 1
}
logDebug Method
You can insert a message into the log, complete with a message and the row values as reported by rules, using the 
logDebug()
 method. This method is the simplest debug approach. For example:
logicContext.
logDebug
("My Message")
For more information about how to output messages to the log by nesting the messages inside the transaction nest level, see View Logging Information.
getTableDefinition Method
You can obtain information about the current table (no argument) or a designated table using the 
getTableDefinition([<tableName>])
 method. This method returns a JavaScript object that includes:
  • Attributes: The attribute names, lengths, type, etc.
  • Parents: The tables that are parents of the current table.
  • Children: Child tables
getResourceDefinition Method
You can obtain information about a designated resource using the 
getResourceDefinition()
 method:
logicContext.
getResourceDefinition
(<resource name>)
This method returns a JavaScript object that includes:
  • The table on which the resource is based.
  • The set of attributes, including their (alias) names, base table names, and whether they are part of a key.