The logicContext Object

The logicContext Object
lac52
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. These methods use the server's database connection and Java Database Connectivity (JDBC) for SQL access.
For more information about logic execution, see Logic Execution.
Limitation:
 You can use the 
logicContext
 object only in the JavaScript for rules that do not reference non-persistent attributes (NPA) or that are not tied to Just In Time (JIT) compilation.
For more information about JIT, see Synchronize Data with Logic.
 You can also interact with data using REST:
  • You can invoke RESTful services (API Creator or others).
  • You can materialize a JSON string from your rows, perhaps as a payload to send to a remote system.
REST results:
  • Do not include role accessors. They are static rows.
  • Are not persistable using the (more convenient) INSERT, UPDATE, and DELETE APIs.
  • Always trigger database access. Often, object accessors find the desired data in memory, and you are assured of seeing other updates in the current transaction.
In this article:
 
 
3
 
 
verb Property
The 
verb
 property defines what the current logic iteration is trying to do, such as 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 Property
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 rules 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');
 This 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. This 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 NPA 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 resource 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
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 or 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.
You can update an object in an action. Call the 
touch()
 method, change a column in the row, and then call the 
update()
 method.
Example:
 
The following code snippet updates an object, calling the 
touch()
 method and the 
update()
 method.
Example:
 
var customer = logicContext.
getBeanByPrimaryKey
("customer", "123");
logicContext.
touch
(customer); // IMPORTANT!
customer.name = 'Updated customer';
logicContext.
update
(customer);
delete() Method
You can delete an object using the 
delete()
 method.
Example:
 
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 
transformCurrentRow()
 method transforms an entity (table or view) row to a resource instance as a JSON string. This method is typically called in event rules. This method provides transformation logic to choose/rename attributes and related objects.
The 
Conference Offers
 API sample includes the 
Alert Management - JSON Message
 event rule that uses this method.
For more information:
  • About how to integrate 
    Layer7 Live API Creator
     with systems using resources as transformation definitions, see Integrate Data and Systems.
rowToJSON() Method
You can convert a row to a JSON structure with appropriate datatypes that can be passed to other persistent document storage systems.
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, such as attribute names, lengths, and type.
  • 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.