Progress
AppBuilder
Developer’s Guide
Mapping Options
Mapping is very like translating from one human language to another. It can be simple or difficult depending on the complexity of the original document and your skill at preserving the underlying meaning.
CAUTION: No type-checking is performed at any stage of the mapping process. You yourself must ensure that the values you produce by mapping or conversion are appropriate and correct.You have a number of mapping options to aid you in your document conversion. You can choose to map a schema node to a:
These options are discussed more fully in the following sections.
Mapping to a Column
This is the simplest and probably the most common mapping. You can use it whenever a column in the data stream corresponds directly to a schema element.
Calculated fields/columns can complicate matters. On the outbound side, mapping a calculated column is identical to mapping an ordinary column. However, since calculated fields have no physical existence in a database, you would have to write special code to make sense of an inbound mapping. Usually, calculated fields are read-only; writing them in a meaningful way requires that you handle the result as a special case, decomposing and folding it back into the original fields in some way that fits your business context.
Mapping to a Function in the SmartB2BObject
If you need to transform or convert a column value in some general way before sending/storing it, you can create a function to do that inside the SmartB2BObject itself. For example, you might create a function to convert dates to some special format, or present an integer value in some unusual base. The Mapping Tool will display any such functions as options when you elect to map to a column.
These conversion functions always have a single parameter:
- For inbound documents, the value of the message element is passed as the parameter and the return value of the function is stored into the data field.
- For outbound documents, the situation is exactly opposite: the data field is passed as the parameter and the return value of the function is used as the message element.
Mapping to a Procedure in the Data-access Object
When you map an XML node to a procedure, you are actually mapping to the procedure’s parameter. The parameter must be an INPUT parameter for inbound documents and an OUTPUT parameter for outbound documents. It must also be the only parameter. You must handle all 4GL data operations inside the body of the procedure.
Mapping to a Function in the Data-access Object
When you map to a function, the exact mapping depends on the direction:
- For inbound documents, you are mapping the schema node to an INPUT parameter. You must handle all assignments to the data field within the body of the function; the return value will be discarded.
- For outbound documents, you are mapping the return value of the function to the schema node. These functions can have no parameters. Handle all data reads within the body of the function.
Mapping to a Whole Data-access Object.
Mapping a whole object to a schema node has a different meaning depending on whether you are creating an inbound or an outbound map.
On the outbound side, the meaning is an implied one: iteration.
Consider the subtree example shown here:
![]()
The fields custnum, name, state, and so forth have obvious mappings to fields in the Customer table. To map those fields to these nodes, you must identify as a resource the SmartDataObject that supplies records from the Customer table.
If the schema allows multiple instances of the Customer element to be generated, and you map the object itself to the Customer node here, then the SmartB2BObject treats that as a request to fetch all Customer records as part of building the message body. It will loop through all Customer records, extracting values for each of the mapped fields (custnum, name, and so forth) and creating XML for them.
The net result of that loop will be multiple Customer record elements, explicitly laid out in the message body. It might look something like this, if the only fields mapped were custnum and name:
Which means that, on the inbound side, no loop is required—simply going through the message in a linear way will traverse all included elements.
On the inbound side, the result of processing the incoming XML is typically operations on a database. When you elect to map a data object to an element, you must identify what sort of operation is desired or acceptable:
- Update (may exist) — Any particular record need not exist. If it does exist, it will be updated and if it does not exist, it will be created.
- Update (must exist) —The record must exist and will be updated as part of the message-consuming process. If the record does not exist, the data handler will report an error.
- Create only— The record must not already exist; it is created as part of the message- consuming process. If the record already exists, the data handler will report an error.
- Delete — The record must exist; it is deleted as part of the message-consuming process. If the record does not exist, the data handler will report an error.
- Find — This operation is used for positioning the current-record pointer in the database.
NOTE: It is also possible to identify the operation within a node of the message itself. Exactly how this is to be done is not well-defined and may vary across document schema. If you face this situation, you must write code to handle it as a special case.To continue the example: if on the inbound side you map the Customer object to the Customer element with a type of Create, then every time the receiving SmartB2BObject sees the <Customer> token in the received message, it will build a Create request using field data from <custnum>, <name>, and so forth. When it reaches the </Customer> token, it will forward the request to the local SmartDataObject that manages that table.
Note that, in this example, Customer cannot be the root node of the schema tree if you intend to generate multiple records; XML only allows one root node. If Customer were the root node, only data from the current record would be transformed into XML.
However, if Customer is not the root node of the schema tree, then all Customer records will be processed. If you want only a subset of all records to be used, you must take steps to ensure that only those records appear in the data stream. Consider using a SmartFilter for that purpose (see the "SmartFilters" section in "Data-access Objects" for details).
CAUTION: If you map an object to some field/column that does not necessarily have unique values across all records, Find, Delete, and Update operations will act on the first acceptable record found. That might not be what you intend or desire.
Copyright © 2004 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |