The logicContext Object

The logicContext Object
lac31
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 tells you 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, you might want to bypass auditing logic when an Order is inserted.
logicNestLevel Property
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 for the duration of 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 in some scenarios.
 
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 User Logic logger:
log.debug('Customer balance is: ' + currentObject.balance); logicContext.
logDebug
('Customer balance is: ' + currentObject.balance);
You cannot use the 
logicContext.logDebug
 (and other methods) in formulas that non-persistent attributes use. Instead, use 
log.debug
. The other variations of this method,
logFiner
and
logFinest
, use a lower level of logging.
Interact with Data
When you create an API and connect API Creator to your database, API Creator builds a JavaScript object model by scanning the database schema. 
CA Live API Creator
 automatically creates a row object type (class) for each base table. If you are using multiple databases, prefix your table name with the database name (for example,
main:Customer
). If your API later adds a second database, including a database prefix avoids requiring that you revise these table references.
For more information about using multiple databases, including best practices, see Integrate Multiple Databases.
createPersistentBean Method
You can create a new object, ready to be inserted, using the
createPersistentBean()
 method.
Example:
var newCustomer = logicContext.
createPersistentBean
("Customer");http://newCustomer.name" scope="external">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. Consider the following code snippet from the Bill of Materials Kit Explosion example. The Bill Of Materials Kit Explosion example is an advanced example used in the training. 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 properly arrange for quantities (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, required for 
    oldRow
    , and 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 wish 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 and is typically called in a table event. This provides transformation logic to select/rename attributes and related objects.
For more information:
Interact with Data using REST
The previous services use the server's database connection and Java Database Connectivity (JDBC) for SQL access. 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.
For more information about invoking RESTful services and materializing JSON strings from rows, see Integration.
 REST vs. Object Access
 In most cases, use the
logicContext
object's services. 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. In many cases, object accessors find the desired data in memory, and you are assured of seeing other updates in the current transaction.
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.
Obtain Metadata Information
You can obtain metadata, that is, information that describes the rows in your API (as distinct from row values) using the 
logicContext
 object.
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(<resourceName>)
 method. This method returns a JavaScript object that includes:
  • Table: The table on which the resource is based.
  • Attributes: The set of attributes, including their (alias) names, base table names, whether they are part of a key, etc.