Posts Tagged ‘Oracle BRM’


Understanding the Oracle BRM Table Structure

September 10th, 2010 by Janell Edwards • 6 Comments »

The Oracle Billing and Revenue Management (BRM) database structure can be confusing at first glance.  Rather than following a typical relational design, BRM was designed to support an object-oriented approach for extensibility.

This post describes the logical relationships that exist between tables so you can get started.

First, a  table is either a Parent table or a Child table.  The Parent tables are usually one word table names with “_t” on the end.  For example:

  • Account_t
  • Bill_t
  • Item_t
  • Event_t
  • Service_t
  • Profile_t
  • Payinfo_t

The Child tables’ names always start with their Parent table’s name.  For example:

  • Account_nameinfo_t (child of account_t)
  • Account_products_t (child of account_t)
  • Event_billing_products_t (child of event_t)
  • Payinfo_cc_t (child of payinfo_t)

Parent tables are logically joined to their Children tables by the poid_id0 (please note that’s a zero at the end of the poid_id string) column in the parent and the obj_id0 column in the Child table.  Here’s a sample select statement:

Parent_table.poid_id0 = child_table.obj_id0

For example, account_t.poid_id0 = account_nameinfo_t.obj_id0

Some Child tables will join back to other Parent tables.  For example account_products_t joins to the service_t table by account_products_t.obj_id0 = service_t.account_obj_id0 and account_products_t.service_obj_id0 = service_t.poid_id0.  These are bi-directionally joined.

===================================================

That above paragraph addresses parent/child table relationships in BRM.  But how do parent tables relate to other parent tables?

Parent tables are joined together by their poid_id0 columns.

Not all parent tables join to each other but when they do it will always be parent_table.poid_id0 = joined_parent_table.<parent_table>_obj_id0.

For example, account_t and service_t are joined by account_t.poid_id0 = service_t.account_obj_id0

It is always easy to see the relationship in the tables by looking at the columns.  Poid_id0, obj_id0, and anything that ends in obj_id0 (like account_obj_id0, service_obj_id0, etc) are the joined columns.

6 Comments »

 

How to Get BRM Pipeline Working

April 9th, 2010 by Mark Peterson • 2 Comments »

I recently installed and configured the BRM pipeline rating using BRM’s optional Wireless Suite.  I had a difficult time getting it to work because it requires installing many interdependent components and many manual configuration steps. Hopefully this blog will help you get it working without much difficulty. Most of the difficulty has to do with figuring out what steps are needed and why.  The BRM documentation has most of the information you need but it is not in one place and it simply tells you to do this or that. It doesn’t do a good job at explaining what is needed to get the pre-configured wireless pipeline to work.  It also doesn’t explain how to create accounts and CDRs that work with the these pre-configured items.  I learned out a lot from getting it to work though. So here’s what I learned.

Pipeline rating is a completely standalone rating engine. These steps take you through the process of configuring the pipeline and BRM system so you can create accounts that the pipeline can work process and then create, rate and load CDRs into BRM. The pipeline needs to have rate plans, zones and other features loaded in the IFW database. BRM needs new event, service, device and item class-types configured.  The pipeline uses some BRM database configuration items to work whereas BRM needs some FMs to handle functionality around the Customer Center extensions. You’ll also need to install the Telephone and SIM Card Administrator.

The basic steps to get it to work are listed here. More details are broken out in the section that follow.

  • Install Customer Center Extensions.
  • Install Server-side Components.
  • Configuring the Wireless Registry File
  • Configure the IFW Database with Default Rate Plans and Settings.
  • Run pin_setup Scripts
  • Configure PIN_REL
  • Load the Telco GSM Event Map
  • Merge and Load Telco Event Notification
  • Create Portal Products, Deal, Plan and add to Plan List
  • Load Device Service Map
  • Load Item Type Mapping
  • Setting up GSM Accounts and Services.
  • Process CDR File
  • Testing and Troubleshooting Pipeline Rating

Install Customer Center Extensions

The first things you’ll need to do is install a panel and it’s associated dialog boxes into Customer Center. This panel is needed to create accounts with telephony services. These services require phone numbers, SIM cards and IMEI numbers in order to maintain, rate, bill and provision the service. BRM added this panel so Customer Service Reps (CSRs) can select telephone numbers, SIM cards and IMEI numbers when creating new accounts.

You will also need to install admin tools used for creating blocks of telephone numbers and SIM cards. The install scripts for these admin tools and the Customer Center extensions are located on http://edelivery.oracle.com.  Select “Oracle Communications Applications” in the drop-down and the OS you’re working with; e.g. Microsoft Windows 32-bit platform. Select search.

Select the “BRM Media Pack for Microsoft Windows (32-bit)” and download Oracle BRM clients for Windows.  After it downloads unzip the file and install these three client components on your PC.

GSM_Mgr_CustCtrExt
NumberAdminCtr
SIMAdminCtr

The install scripts assume you have Customer Center already installed and it usually finds the installation directory by itself. The installation of these client side components is easy. After you unzip the packages, just execute the setup.exe file and follow the instructions.

Install Server-side Components

Since the pipeline rating engine is not part of BRM, some some new op-codes are needed by BRM.   Although you have installed the pipeline rating engine on the server, you not done yet. There are several more components you will need. If you haven’t installed the pipeline rating engine, I blogged about it in, Common BRM Pipeline Installation Issues.

If you don’t have the install scripts shown below, you’ll need to go to Oracle e-delivery site and download the optional BRM components. It’s under the Oracle BRM Media Pack ->Oracle BRM Extensions.

Unzip the file and run these install scripts as the PIN user. The actual names may be a little different depending upon the version and platform you’re using.

7.4_WirelessSuite_linux_32_opt.bin
7.4_SIMMgr_linux_32_opt.bin
7.4_NumberMgr_linux_32_opt.bin
7.4_GPRS_Mgr_30_linux_32_opt.bin
7.4_GSM_Mgr_linux_32_opt.bin

Configuring the Wireless Registry File

When you install the Wireless Suite component, it comes with a pre-configured wireless pipeline. The registry for this pipeline is located in the the IFW_HOME/conf directory and is called wireless.reg.  You will need to edit this file by entering the connection information you used for setting up the IFW and PIN database. It needs the database alias, and user name and passwords you used. There is one entry for the IFW database and two entries for the PIN database. You will need to encrypt the passwords using AES encryption.

Next you will need to create an IFW synchronization queue.  The wireless pipeline registry, wireless.reg,  calls the sync queue IFW_SYNC_QUEUE. It is created by running the pin_ifw_sync_oracle.pl scripts. I couldn’t get it to work taking some of the default values as shown in the script usage syntax.

pin_ifw_sync_oracle.pl create [-l username/password@databaseAlias] [-q queue_name -t queue_table]

After including the following command line options, I was able to get it to work. You will need to modify this for your particular environment.

perl pin_ifw_sync_oracle.pl create -l pin74/pin74@pindb -r 300 -s ‘tablespace PIN74 initrans 5 storage (initial 200k next 200k maxextents unlimited pctincrease 0 )’

Configure the IFW Database with Default Rate Plans and Settings.

The BRM Wireless Suite comes with a pre-configured set of rate plans, discounts, impact categories, etc.  These settings are stored in the IFW_HOME/conf/pricingcenter/Oracle directory.

Edit the perl script called insertWIRELESS_SAMPLE.pl in this directory. Change the oracle connection properties to use the IFW database alias and user name and password you chose. When you run this script it will execute the insert statements contained in the SQL scripts located in this directory. You will notice that each SQL script is named after the IFW table it updates. This makes it very easy to see what is being added to the IFW database. As you can see, there are a lot of tables  affected by running this perl script.

ifw_alias_map.sql ifw_apn_group.sql ifw_apn_map.sql
ifw_calendar.sql ifw_daycode.sql ifw_destinationdesc.sql
ifw_discarding.sql ifw_discountbalimpact.sql ifw_discountcondition.sql
ifw_discountdetail.sql ifw_discountmaster.sql ifw_discountmdl_cnf.sql
ifw_discountmdl_ver.sql ifw_discountmodel.sql ifw_discountrule.sql
ifw_discountstep.sql ifw_discounttrigger.sql ifw_edrc_desc.sql
ifw_edrc_field.sql ifw_exchange_rate.sql ifw_glaccount.sql
ifw_holiday.sql ifw_icproduct_all.sql ifw_impact_category.sql
ifw_map_group.sql ifw_mostcalled.sql ifw_networkmodel.sql
ifw_networkoper.sql ifw_pipeline.sql ifw_pricemodel.sql
ifw_pricemodel_step.sql ifw_rateplan_cnf.sql ifw_rateplan.sql
ifw_rateplan_ver.sql ifw_ref_map.sql ifw_resource.sql
ifw_rsc_group.sql ifw_seqcheck.sql ifw_serviceclass.sql
ifw_servicecode_map.sql ifw_service.sql ifw_specialday_lnk.sql
ifw_specialdayrate.sql ifw_splittingtype_all.sql ifw_standard_zone.sql
ifw_taxcode.sql ifw_taxgroup.sql ifw_tax.sql
ifw_timeinterval.sql ifw_timemodel_lnk.sql ifw_timemodel.sql
ifw_timezone.sql ifw_uom.sql ifw_usageclass_map.sql
ifw_usageclass.sql ifw_usagescenario_map.sql ifw_usagetype.sql
ifw_usc_group.sql ifw_zonemodel.sql

To run this command, be sure to redirect the output to a file. It streams a bunch of information to the standard output. It doesn’t output to a log file so you may want to look back this file to be sure it ran properly.

Run pin_setup Scripts

As a pin user, go to $PIN_HOME/setup/scripts

Run the pin_cmp_tcframework.pl file. This install script creates a bunch of new classes (tables) in the PIN database. Expand the nodes below to see what tables where created:

Service Objects:

/service/telco/
/service/telco/gsm/roaming

Event Objects

/event/activity/telco
/event/session/telco
/event/delayed/activity/telco
/event/delayed/session/telco
/event/delayed/activity/telco/roaming
/event/delayed/session/telco/gsm/roaming
/event/svc_order
/event/svc_order/attribute
/event/provisioning
/event/provisioning/service_order

Config Objects:

/config/telco/provisioning
/config/telco/provisioning/fieldlist
/config/telco/service_order_state
/config/telco/service_order_state/telco
/config/service_framework
/config/service_framework/permitted_service_types/
/config/account_era

Run the perl pin_cmp_gsm.pl script Expand the following nodes to see what tables (classes) are created.

Service Objects

/service/settlement
/service/settlement/roaming
/service/telco/gsm
/service/telco/gsm/data
/service/telco/gsm/fax
/service/telco/gsm/sms
/service/telco/gsm/telephony
/service/telco/gsm/roaming
/service/settlement/roaming
/service/settlement/roaming/incollect
/service/settlement/roaming/outcollect

Event Objects:

/event/activity/settlement
/event/session/telco/gsm
/event/delayed/session/telco/gsm
/event/delayed/session/telco/gsm/roaming
/event/provisioning/service_order/telco/gsm
/event/provisioning/service_order/telco/gsm/data
/event/provisioning/service_order/telco/gsm/fax
/event/provisioning/service_order/telco/gsm/sms
/event/provisioning/service_order/telco/gsm/telephony

Config Objects:

/config/telco/gsm
/config/telco/gsm/data
/config/telco/gsm/fax
/config/telco/gsm/sms
/config/telco/gsm/telephony
/config/telco/service_order_state/gsm
/config/telco/service_order_state/data
/config/telco/service_order_state/fax
/config/telco/service_order_state/sms
/config/telco/service_order_state/telephony

Active_session objects:

/active_session/telco/gsm
/active_session/telco
/active/session/telco/gsm

Run the pin_cnf_tcframework.pl script. This will add the following FMs to the CM pin.conf file. These FMs contain opcodes used by the Customer Center.

fm_prov fm_prov_pol
fm_tcf fm_tcf_pol
fm_trans_pol

Run the pin_cmf_dm_prov_telco.pl and pin_cnf_dm_prov_telco.pl

This will configure the CM pin.conf file and dm_prov_telco pin.conf file. You may also want to edit the start_all and stop_all script so that dm_prov_telco start and stops with the rest of the CM and DMs.

Configure PIN_REL

There are several traps you can fall into trying to get the pin_rel utility to work for the first time. You will need to run some setup/scripts, modify the user $PATH and make sure Oracle sqlldr is installed on the server.  This section will help you avoid some common problems.

First, the pin_rel utility requires some new tables in the database schema to operate. Go to the setup/scripts directory and run the pin_cmf_rel.pl and pin_cnf_rel.pl. Next add the $PIN_HOME/apps/pin_rel to the pin user $PATH.  And finally be sure Oracle sqlldr is installed on the server.

The pin_rel utility use SQL Loader (sqlldr) to load events into the BRM database. To see if it is installed on your server, executing sqlldr from the command line as the pin user. If it can’t be found check to be sure the $ORACLE_HOME/bin directory is in the path. If sqlldr isn’t in the bin directory, then install it. It’s part of the Oracle database installation so you will basically have to install Oracle on the server. Since you don’t actually need a configured database on the server, skipping this step during installation will save you some time.

For performance reasons you may want to run on the database server. When you run CDRs through the pipeline, you can map the output to a network drive or copy the files to database server.  For our testing purposes  running it on the BRM server is sufficient. If you have a large amounts of EDRs to process in production and to load into BRM, then you may need to move the pin_rel app over to the database server.

Load the Telco GSM Event Map

The Pricing Center needs to be configured to recognize the new event and service objects loaded in prior steps. Fortunately the new event map is created for you. This event map comes already merged with BRM base-line event maps. If you’re working with a baseline BRM installation,  you just have to load them into the database.

Change directory to sys/data/config directory and run the command:

load_event_map -dv pin_event_map_telco_gsm

If you have custom events already loaded, then be sure to edit the pin_event_map_telco_gsm file before you run this command. This command will overright the changes made to the default event map, if you don’t. If you forget, just rerun the command with custom events added to this file.

Merge and Load Telco Event Notification

The Telco provisioning is integrated through the event notification framework. When new products and services are purchased for an account, the event notification framework needs to fire-off these op-codes. These op-codes will perform functionality required to provisioning the new telephony services through BRMs provisioning framework.

PCM_OP_TELCO_SVC_LISTENER 4008
PCM_OP_TELCO_APPLY_PARAMETER 4009
PCM_OP_TELCO_PROPAGATE_STATUS 4010
PCM_OP_TELCO_PROV_CREATE_SVC_ORDER 4016
PCM_OP_TELCO_PROV_HANDLE_SVC_ORDER 4017
PCM_OP_TELCO_PROV_UPDATE_PROV_OBJECT 4019

To enable the provisioning framework, change to following directory to sys/data/config and execute

load_pin_notify pin_notify_telco

Create Portal Products, Deal, Plan and add to Plan List

In this section you will create a product, deal and a plan that can be purchased against accounts and rate CDRs through the pipeline.  We will use one of the rate plans inserted in the pipeline database with the insertWIRELESS_SAMPLE.pl script described above.  Start Pricing Center and connect to the PIN database. Click on the create product icon, enter a name and select in the drop-down list Applies To: /service/telco/gsm/telephony.

Accept all the default values and when you get the prompt, “Do you want to add or change rates and folds for this product?”, click on “Yes”. Now add an Event Map and locate “Delayed Session GSM Session”.  This should give you a menu of Pipeline Single Rate Plans. Click on “Search/Reload” This pop-up window should look like this:

Click and then “Select” the GSM Sample Rate Plan. Apply changes. Next create a deal and a plan for this product. Add the Plan to the default plan list. Commit changes to the database.

Load Device Service Map

load_pin_device_permit_map pin_device_permit_map_sim_telco_gsm

load_pin_device_permit_map pin_device_permit_map_num_telco_gsm

Load Item Type Mapping

The events rated by the pipeline engine requires an /item object to associate these charges together for an account. The documentation provides examples for associating charge from New York or California to /item/gsm/new_york or item/gsm/california. For sake of simplicity we will just associate all pipeline rates events to /item/usage/gsm. To do this,   you will need to edit two xml files in the $PIN_HOME/sys/data/pricing/examples directory; config_item_tags.xml and config_item_types.xml.  Add the contents for <ItemTagElement> to the following files as shown below:

config_item_tags.xml

<ItemTagElement>
<ItemTag>gsm</ItemTag>
<EventType>/event/delayed/session/telco/*</EventType>
<ServiceType>/service/telco/gsm/*</ServiceType>
</ItemTagElement>

config_items_types.xml

<ItemTypeElement>
<ItemTag>gsm</ItemTag>
<ItemDescription>GSM Usage</ItemDescription>
<ItemType precreate=”true” type=”cumulative”>/item/usage/gsm</ItemType>
</ItemTypeElement>

To load these configuration files using the following utilities:

load_config_item_tags -dv config_item_tags.xml

load_config_item_types -dv config_item_types.xml

Using Developer Center extend the /item/usage to /item/usage/gsm. To do this start Developer Center, click on the Storable Class Editor   and click on the /item/usage class in the class window.  Then click File->New->Class and add “/gsm” to the base class.  And finally click on File->Commit Class to Database

If you get a permission error message committing these changes, recall that the DM_ORACLE pin.conf file needs to be set to enabled to changes to the class and field definitions, see below:

- dm dd_write_enable_fields 1

- dm dd_write_enable_objects 1

You will have to restart the BRM to load these changes.

Setting up GSM Accounts and Services.

Before you can create accounts using the GSM plan created in Pricing Center, you will need to load up a set of test phone numbers and SIM cards to use. What SIM card and phone number you specify will matter for testing. For instance, the pipeline will not rate any out of network calls. So all the CDRs you create to test in the pipeline will have to use phone numbers associated with accounts and services setup in BRM. But before you can do that you will need to establish a block of available numbers to select from.

I found the documentation very good for learning how to use the Number and SIM Card Administrator. These applications are used to set up a block of numbers and SIM cards that can be consumed by account telephony services in BRM. The Number Administrator was straight forward and easy to use. There are a couple things to note, however, when using the Number and SIM Card Administrator.

1) Load SIM Card types before running the SIM Card Administrator. From the PIN_HOME/sys/msgs/simcardtypes directory load the SIM card types by using the load_localized_string utility from the command line:

load_localized_strings sim_card_types.en_US

2) Use known good test SIM cards numbers.  To create a block of SIM cards you first have to order them in the SIM Card Administrator. After they are ordered you will need to fulfill the order. To make this easier, refer to the end of documentation for configuring the SIM Card Administrator. It contains a set of test SIM card numbers you can use to test with. If you don’t use these numbers, you’ll have to figure out valid fulfillment data used to activate the order.

Normally you would export a file and send this file to a supplier of SIM cards. The SIM card manufacturer would return an order fulfillment so you can activate the numbers for BRM to consume.  For testing purposes you will export the order and modify the order with test data provided in the documentation. As described in the documentation, it involves appending some order fulfillment code to the end of the exported order and then loading them back into the SIM Card Administrator.

3) Set the status to “Not Specified” when searching for SIM cards in the Customer Administrator.  When you search for SIM cards in the Customer Center, it searches through available devices (/device/sim) for SIM cards with a status of released. You can either configure the SIM Card Administrator to include “New” status, or change the status to “Not Specified”.

4) Coordinate test phone numbers with zone mapping values and CDR test data. If you plan to leverage pre-configured zone mappings and sample CDRs then you might consider creating a block of phone numbers to include these numbers. If you don’t you’ll have to edit the sample CDRs to include the ones you did use and determine how the numbers are rated and mapped in the zone map.  For reference, I included some phone numbers used in the sample CDRs. These CDRs I found in the IFW_HOME/data/in directory in a file called test_cdr.orig. The second and third field in the files are the source and destination numbers of the CDR. Again, both source and destination numbers need to be used by accounts in BRM for them to rate. No out of network phone calls will work.

TEL;00491732410;004941067600;20011114184300;300;0;0;NORM;123456;
TEL;00491732411;004941067600;20011114184300;270;0;0;NORM;123456;
TEL;00491732412;004941067600;20011114184300;110;0;0;NORM;123456;
DAT;00491732413;004941067600;20011114184300;50;0;0;NORM;123456;
FAX;00491732414;004941067600;20011114184300;12;0;0;NORM;123456;
TEL;00491732415;004941067600;20011114184300;1;0;0;NORM;123456;
SMS;00491732416;004941067600;20011114184300;63;0;0;NORM;123456;
TEL;00491732417;004941067600;20011114184300;37;0;0;NORM;123456;
TEL;00491732418;004941067600;20011114184300;132;0;0;NORM;123456;
TEL;00491732419;004941067600;20011114184300;60;0;0;NORM;123456;
TEL;00491732420;004941067600##;20040601184300;300;0;0;NORM;123456;
GPRT;00491732410;0049;20011114184510;300;78965;5054;;001121;hamburg.portal.com
GPR;00491732410;0049;20011114184510;300;78965;5054;;001121;hamburg.portal.com

And these where pulled out of the wireless.readme file:

TEL;00491729183333;004941067600;20011114184510;300;0;0;;;
TEL;00491729183333;004941067600;20011114184510;300;0;0;Mail;47113;
TEL;00491729183333;004941067600;20011114184510;300;0;0;Conf;98765; TEL;00491729183333;004941067600;20011114184510;300;0;0;MOC;238476;

Once you have a block of numbers and SIM cards configured, you can create accounts. Using Customer Center, create accounts to include phone numbers you plan to use for testing.

Process CDR File

Start up pipeline using the following command in $IFW_HOME.

ifw -r /conf/wireless.reg

Create CDR file and place into /conf/data/in

Testing and Troubleshooting Pipeline Rating

The error messages provided by the Pipeline Rating engine makes is somewhat easy locate problems. The most helpful messages are located in the $IFW_HOME/log/stream directory.  You will find two sets of logs for each input file, Stream_test_XXXX.edr.log and log_test_XXXX.edr.log. If you have CDRs in the data/in directory that don’t make it to the data/out/gsm/* check here for errors. The most common errors I found where problems with the ITEM_TAG value (being null) and problems with out of network phone numbers.  If you’re having trouble with ITEM_TAG numbers, review the section on Item Tag Mapping. If you have error message for out of network phone numbers, remember that both source and destination phone numbers need to be consumed by accounts  (in network) in order for them to be rated.

2 Comments »

 

Searches Continued: Step Searches (PCM_OP_STEP_SEARCH, PCM_OP_STEP_NEXT, and PCM_OP_STEP_END)

March 24th, 2010 by Allan Anderson • No Comments »

Continuing our discussion on BRM searches, lets talk about step searches.

In many cases the number of results to be returned will overwhelm the regular PCM_OP_SEARCH op-code.  This can basically cause your PCM context to become unusable and can cause some problems in your DM.  Therefore, efforts should be made to search using PCM_OP_STEP_SEARCH when the result set may become very large.

PCM_OP_STEP_SEARCH Input FLIST

The input FLIST is the same as the input for PCM_OP_SEARCH op-code, but is done in 3 discrete steps:

1.  Call PCM_OP_STEP_SEARCH to start the step search.  Returns the first result set based on the number specified in the PIN_FLD_RESULTS array element ID.  After this point, no op-codes may be called on this context other than PCM_OP_STEP_NEXT and PCM_OP_STEP_END until after the PCM_OP_STEP_END op-code is called.
2.  Call PCM_OP_STEP_NEXT repeatedly using the same input FLIST until all the desired results have been retrieved.
3.  Call PCM_OP_STEP_END to end the step search, and free the context to be able to call other op-codes.

Step Search Result FLISTs

The results FLISTs returned from PCM_OP_STEP_SEARCH and PCM_OP_STEP_NEXT are identical to that of PCM_OP_SEARCH.  The results from PCM_OP_STEP_NEXT will be the input FLIST from PCM_OP_STEP_SEARCH, and may be safely ignored.

Example:
Note the Rec ID of 5 in the PIN_FLD_RESULTS array will determine the result set ‘chunk’ size.

nap> d 1
# number of field entries allocated 20, used 5
0 PIN_FLD_POID           POID [0] 0.0.0.1 /search -1 0
0 PIN_FLD_RESULTS       ARRAY [5] allocated 20, used 3
1     PIN_FLD_POID           POID [0] NULL poid pointer
1     PIN_FLD_CREATED_T    TSTAMP [0] (0)
1     PIN_FLD_NAMEINFO      ARRAY [*] allocated 20, used 2
2         PIN_FLD_LAST_NAME       STR [0] NULL str ptr
2         PIN_FLD_FIRST_NAME      STR [0] NULL str ptr
0 PIN_FLD_ARGS          ARRAY [1] allocated 20, used 1
1     PIN_FLD_NAMEINFO      ARRAY [*] allocated 20, used 1
2         PIN_FLD_FIRST_NAME      STR [0] "%a%"
0 PIN_FLD_TEMPLATE        STR [0] "select X from /account where F1 like V1 "
0 PIN_FLD_FLAGS           INT [0] 0
nap> xop PCM_OP_STEP_SEARCH 0 1
xop: opcode 17, flags 0
# number of field entries allocated 6, used 6
0 PIN_FLD_POID           POID [0] 0.0.0.1 /search -1 0
0 PIN_FLD_RESULTS       ARRAY [0] allocated 3, used 3
1     PIN_FLD_POID           POID [0] 0.0.0.1 /account 35862893 19
1     PIN_FLD_CREATED_T    TSTAMP [0] (1268321292) 03/11/10 09:28:12
1     PIN_FLD_NAMEINFO      ARRAY [1] allocated 2, used 2
2         PIN_FLD_LAST_NAME       STR [0] "Fuhes-Monari"
2         PIN_FLD_FIRST_NAME      STR [0] "Debrah"
0 PIN_FLD_RESULTS       ARRAY [1] allocated 3, used 3
1     PIN_FLD_POID           POID [0] 0.0.0.1 /account 33265410 2065
1     PIN_FLD_CREATED_T    TSTAMP [0] (1238622641) 04/01/09 16:50:41
1     PIN_FLD_NAMEINFO      ARRAY [1] allocated 2, used 2
2         PIN_FLD_LAST_NAME       STR [0] "Ogrlo"
2         PIN_FLD_FIRST_NAME      STR [0] "Micael"
0 PIN_FLD_RESULTS       ARRAY [2] allocated 3, used 3
1     PIN_FLD_POID           POID [0] 0.0.0.1 /account 35856912 42
1     PIN_FLD_CREATED_T    TSTAMP [0] (1267800937) 03/05/10 08:55:37
1     PIN_FLD_NAMEINFO      ARRAY [1] allocated 2, used 2
2         PIN_FLD_LAST_NAME       STR [0] "Christen"
2         PIN_FLD_FIRST_NAME      STR [0] "Beaud"
0 PIN_FLD_RESULTS       ARRAY [3] allocated 3, used 3
1     PIN_FLD_POID           POID [0] 0.0.0.1 /account 28715619 15211
1     PIN_FLD_CREATED_T    TSTAMP [0] (1187360056) 08/17/07 09:14:16
1     PIN_FLD_NAMEINFO      ARRAY [1] allocated 2, used 2
2         PIN_FLD_LAST_NAME       STR [0] "Bianc"
2         PIN_FLD_FIRST_NAME      STR [0] "Gin"
0 PIN_FLD_RESULTS       ARRAY [4] allocated 3, used 3
1     PIN_FLD_POID           POID [0] 0.0.0.1 /account 34456511 191
1     PIN_FLD_CREATED_T    TSTAMP [0] (1252009050) 09/03/09 15:17:30
1     PIN_FLD_NAMEINFO      ARRAY [1] allocated 2, used 2
2         PIN_FLD_LAST_NAME       STR [0] "Gog"
2         PIN_FLD_FIRST_NAME      STR [0] "Dhub"
nap> xop PCM_OP_STEP_NEXT 0 1
xop: opcode 18, flags 0
# number of field entries allocated 6, used 6
0 PIN_FLD_POID           POID [0] 0.0.0.1 /search -1 0
0 PIN_FLD_RESULTS       ARRAY [0] allocated 3, used 3
1     PIN_FLD_POID           POID [0] 0.0.0.1 /account 25469857 53148
1     PIN_FLD_CREATED_T    TSTAMP [0] (1139417895) 02/08/06 10:58:15
1     PIN_FLD_NAMEINFO      ARRAY [1] allocated 2, used 2
2         PIN_FLD_LAST_NAME       STR [0] "Amed"
2         PIN_FLD_FIRST_NAME      STR [0] "Ronaldo"
0 PIN_FLD_RESULTS       ARRAY [1] allocated 3, used 3
1     PIN_FLD_POID           POID [0] 0.0.0.1 /account 19702828 1543
1     PIN_FLD_CREATED_T    TSTAMP [0] (1054135772) 05/28/03 10:29:32
1     PIN_FLD_NAMEINFO      ARRAY [1] allocated 2, used 2
2         PIN_FLD_LAST_NAME       STR [0] "Prestoni"
2         PIN_FLD_FIRST_NAME      STR [0] "Markus"
0 PIN_FLD_RESULTS       ARRAY [2] allocated 3, used 3
1     PIN_FLD_POID           POID [0] 0.0.0.1 /account 11102409 3401
1     PIN_FLD_CREATED_T    TSTAMP [0] (996669081) 08/01/01 07:31:21
1     PIN_FLD_NAMEINFO      ARRAY [1] allocated 2, used 2
2         PIN_FLD_LAST_NAME       STR [0] "Kulkar"
2         PIN_FLD_FIRST_NAME      STR [0] "Rahu"
0 PIN_FLD_RESULTS       ARRAY [3] allocated 3, used 3
1     PIN_FLD_POID           POID [0] 0.0.0.1 /account 35624677 146
1     PIN_FLD_CREATED_T    TSTAMP [0] (1265060079) 02/01/10 15:34:39
1     PIN_FLD_NAMEINFO      ARRAY [1] allocated 2, used 2
2         PIN_FLD_LAST_NAME       STR [0] "Johnson"
2         PIN_FLD_FIRST_NAME      STR [0] "Bryan"
0 PIN_FLD_RESULTS       ARRAY [4] allocated 3, used 3
1     PIN_FLD_POID           POID [0] 0.0.0.1 /account 29737931 520
1     PIN_FLD_CREATED_T    TSTAMP [0] (1199807442) 01/08/08 09:50:42
1     PIN_FLD_NAMEINFO      ARRAY [1] allocated 2, used 2
2         PIN_FLD_LAST_NAME       STR [0] "Degad"
2         PIN_FLD_FIRST_NAME      STR [0] "Joaq"
nap> xop PCM_OP_STEP_NEXT 0 1
xop: opcode 18, flags 0
# number of field entries allocated 6, used 6
0 PIN_FLD_POID           POID [0] 0.0.0.1 /search -1 0
0 PIN_FLD_RESULTS       ARRAY [0] allocated 3, used 3
1     PIN_FLD_POID           POID [0] 0.0.0.1 /account 30425794 264
1     PIN_FLD_CREATED_T    TSTAMP [0] (1207179142) 04/02/08 18:32:22
1     PIN_FLD_NAMEINFO      ARRAY [1] allocated 2, used 2
2         PIN_FLD_LAST_NAME       STR [0] "Lena"
2         PIN_FLD_FIRST_NAME      STR [0] "Mich"
0 PIN_FLD_RESULTS       ARRAY [1] allocated 3, used 3
1     PIN_FLD_POID           POID [0] 0.0.0.1 /account 17981207 1255
1     PIN_FLD_CREATED_T    TSTAMP [0] (1034890106) 10/17/02 16:28:26
1     PIN_FLD_NAMEINFO      ARRAY [1] allocated 2, used 2
2         PIN_FLD_LAST_NAME       STR [0] "Payable"
2         PIN_FLD_FIRST_NAME      STR [0] "National Accounts"
0 PIN_FLD_RESULTS       ARRAY [2] allocated 3, used 3
1     PIN_FLD_POID           POID [0] 0.0.0.1 /account 33730335 4148
1     PIN_FLD_CREATED_T    TSTAMP [0] (1244205808) 06/05/09 07:43:28
1     PIN_FLD_NAMEINFO      ARRAY [1] allocated 2, used 2
2         PIN_FLD_LAST_NAME       STR [0] "Weav"
2         PIN_FLD_FIRST_NAME      STR [0] "Garr"
0 PIN_FLD_RESULTS       ARRAY [3] allocated 3, used 3
1     PIN_FLD_POID           POID [0] 0.0.0.1 /account 13422861 68934
1     PIN_FLD_CREATED_T    TSTAMP [0] (1008632620) 12/17/01 17:43:40
1     PIN_FLD_NAMEINFO      ARRAY [1] allocated 2, used 2
2         PIN_FLD_LAST_NAME       STR [0] "Payable"
2         PIN_FLD_FIRST_NAME      STR [0] "In care of Arba - Accounts"
0 PIN_FLD_RESULTS       ARRAY [4] allocated 3, used 3
1     PIN_FLD_POID           POID [0] 0.0.0.1 /account 16507073 3046
1     PIN_FLD_CREATED_T    TSTAMP [0] (1025313455) 06/28/02 20:17:35
1     PIN_FLD_NAMEINFO      ARRAY [1] allocated 2, used 2
2         PIN_FLD_LAST_NAME       STR [0] "Bain"
2         PIN_FLD_FIRST_NAME      STR [0] "Satn"
nap> xop PCM_OP_STEP_END 0 1
xop: opcode 19, flags 0
# number of field entries allocated 6, used 6
0 PIN_FLD_POID           POID [0] 0.0.0.1 /search -1 0
0 PIN_FLD_RESULTS       ARRAY [5] allocated 3, used 3
1     PIN_FLD_POID           POID [0] NULL poid pointer
1     PIN_FLD_CREATED_T    TSTAMP [0] (0)
1     PIN_FLD_NAMEINFO      ARRAY [*] allocated 2, used 2
2         PIN_FLD_LAST_NAME       STR [0] NULL str ptr
2         PIN_FLD_FIRST_NAME      STR [0] NULL str ptr
0 PIN_FLD_ARGS          ARRAY [1] allocated 1, used 1
1     PIN_FLD_NAMEINFO      ARRAY [*] allocated 1, used 1
2         PIN_FLD_FIRST_NAME      STR [0] "%a%"
0 PIN_FLD_TEMPLATE        STR [0] "select X from /account where F1 like V1 "
0 PIN_FLD_FLAGS           INT [0] 0
0 PIN_FLD_OP_CORRELATION_ID    STR [0] "1:AANDERSON::7428:6596:19:1269464323:4"

No Comments »

 

Oracle BRM Blog: All About Searches (PCM_OP_SEARCH)

March 22nd, 2010 by Allan Anderson • 2 Comments »

Today’s blog entry is all about how to construct and write searches in BRM.  Specifically, this relates to the PCM_OP_SEARCH op-code (Op-Code #7) and its input and output FLISTs.

Searches play an important part in most BRM applications and customizations.  Bending them to your will is an important skill to have.

Elements of PCM_OP_SEARCH:  Input and Output FLISTs

For every op-code, there is an input and output FLIST.  Since any search in BRM is just another op-code call, the same rule applies.

The PCM_OP_SEARCH Input FLIST:

To implement any search (not just BRM), we must know the following:

  • What object are we searching for?
  • What search criteria will be used to define the object we are looking for?

For our example, let us say we are looking for an /account object based on customer last name.  Consulting our Data Dictionary in Developer Center, we can look at the structure of the account object:

We see that the last name is stored on the PIN_FLD_NAMEINFO array element in the PIN_FLD_LAST_NAME field.

Now that we know what we want to search for, lets look at the elements of the input FLIST.

PIN_FLD_POID

This field is used to indicate the database to be searched and the search template to use in conducting the search.  A search POID ID of -1 indicates that a custom search template will be passed in on the input FLIST.  If the search POID is positive, then the search template from the appropriate /search object will be used and a template need not be present on the Input FLIST.

Examples:

This POID indicates the use of a custom search template as a part of the INPUT flist.

0 PIN_FLD_POID           POID [0] 0.0.0.1 /search -1 0

This POID indicates that search template 201 will be used.

0 PIN_FLD_POID           POID [0] 0.0.0.1 /search 201 0

Looking in the search_t table in the PIN database, we see that the corresponding template is ‘select X from /account/$1 where F1 = V1 ‘

PIN_FLD_TEMPLATE

This string field is only required if the search template used has a POID ID of -1.  It looks similar to SQL, and MUST include a blank space at the end (this is a great interview question to gauge someone’s BRM development expertise, by the way).

The template must include the object to be searched for as well as the arguments to be used for conducting the search.

select X from <object type> where <arguments>

Object type subclasses may be specified dynamically using a Parameter.  The Parameter is specified by the use of the ‘$1’ string appended to the object type.  If the object type contains a parameter, then the PIN_FLD_PARAMETER field must be present on the input FLIST.  See the PIN_FLD_PARAMETER section below.

Arguments are specified by the use of F<n> and V<n> variables.  F<n> stands for the field to be compared, and V<v> stands for the value of the field to be compared.  The <n> value corresponds directly to an array element of PIN_FLD_ARGS that contains exactly one field and value.  See the PIN_FLD_ARGS section below.  Most SQL operators may be used to compare the arguments ( =, <>, IS NOT NULL, like, etc.).

Examples:

This template is a 1 argument search for /deal objects:

This search template requires the PIN_FLD_ARGS[1] Array element to be present on the search FLIST.

0 PIN_FLD_TEMPLATE        STR [0] "select X from /deal where F1 = V1 "

This template is a 2 argument search for /account objects:

Notice here that we have a parameter for the object type, which requires the presence of the PIN_FLD_PARAMETER field on the input FLIST.  PIN_FLD_ARGS[1] and PIN_FLD_ARGS[2] are also required.

0 PIN_FLD_TEMPLATE        STR [0] "select X from /account/$1 where F1 = V1 and F2 <> V2 "

PIN_FLD_ARGS

This array holds the search criteria utilized by the F<n> and V<n> values in the search template.  The <n> specifies the array element to be used for that search expression.

The following combination of PIN_FLD_TEMPLATE and PIN_FLD_ARGS:

0  PIN_FLD_TEMPLATE    STR [0] “select X from /deal where F1 = V1 ”
0  PIN_FLD_ARGS [1]
1    PIN_FLD_NAME STR [0] “Network Storage”

Can be logically said to translate to:

select X from /deal where PIN_FLD_NAME = ‘Network Storage’

PIN_FLD_PARAMETER

This field allows the object type being searched for to be subclassed for the search in question.

If we want to search for /event/session, the following FLIST could be used:

0 PIN_FLD_TEMPLATE    STR [0] “select X from /event/$1 where F1 = V1 ”
0 PIN_FLD_PARAMETER  STR[0] “session”

If the subtype is a separate variable in our code, this becomes useful for making sure the appropriate sub-classes are returned.

PIN_FLD_FLAGS

The flags field is used to dictate the behavior of the search.  Possible values for the flags include:

Zero (0):  No search flags.  Return all results found.

SRCH_DISTINCT (256):  Do not return multiple instances of the same object in the search results.

SRCH_EXACT (512):  Do not return array elements that do not match the search criteria.

PIN_FLD_RESULTS

This array element defines which fields from the result set should be returned, as well as how many results should be returned.

Examples:

Returns all object fields and an unlimited number of results:

0 PIN_FLD_RESULTS       ARRAY [*]     NULL array ptr

Returns all object fields and the first 25 matching objects:

0 PIN_FLD_RESULTS       ARRAY [25]     NULL array ptr

Returns only the PIN_FLD_NAME and PIN_FLD_POID fields from all matching objects:

0 PIN_FLD_RESULTS       ARRAY [*]
1  PIN_FLD_POID               POID[0] NULL
1  PIN_FLD_NAME              STR[0] NULL

PCM_OP_SEARCH Result FLIST:

Search results include a PIN_FLD_POID field equal to the one passed on the input FLIST, plus a PIN_FLD_RESULTS array element for each object found that matches the search criteria.

The elements in PIN_FLD_RESULTS could include the whole object found, or a subset, depending on the PIN_FLD_RESULTS passed in on the Input search FLIST.

If no PIN_FLD_RESULTS array elements are returned, the search did not return any objects that matched the search criteria.

Putting it All Together: Some Examples

This section contains some example searches to highlight the above points.

Custom Template Unlimited Result Search for Deal by Name:

# number of field entries allocated 20, used 5
0 PIN_FLD_POID           POID [0] 0.0.0.1 /search -1 0
0 PIN_FLD_RESULTS       ARRAY [*]     NULL array ptr
0 PIN_FLD_ARGS          ARRAY [1] allocated 20, used 1
1     PIN_FLD_NAME            STR [0] "Deal 1a - Measured Internet Service"
0 PIN_FLD_TEMPLATE        STR [0] "select X from /deal where F1 = V1 "
0 PIN_FLD_FLAGS           INT [0] 0
nap> xop 7 0 1
xop: opcode 7, flags 0
# number of field entries allocated 2, used 2
0 PIN_FLD_POID           POID [0] 0.0.0.1 /search -1 0
0 PIN_FLD_RESULTS       ARRAY [0] allocated 13, used 13
1     PIN_FLD_POID           POID [0] 0.0.0.1 /deal 8686 2
1     PIN_FLD_CREATED_T    TSTAMP [0] (976219881) 12/07/00 14:11:21
1     PIN_FLD_MOD_T        TSTAMP [0] (995621794) 07/20/01 04:36:34
1     PIN_FLD_READ_ACCESS     STR [0] "B"
1     PIN_FLD_WRITE_ACCESS    STR [0] "S"
1     PIN_FLD_ACCOUNT_OBJ    POID [0] 0.0.0.1 /account 1 0
1     PIN_FLD_DESCR           STR [0] ""
1     PIN_FLD_END_T        TSTAMP [0] (0)
1     PIN_FLD_FLAGS           INT [0] 0
1     PIN_FLD_NAME            STR [0] "Deal 1a - Measured Internet Service"
1     PIN_FLD_PERMITTED       STR [0] "/service/ip"
1     PIN_FLD_START_T      TSTAMP [0] (0)
1     PIN_FLD_PRODUCTS      ARRAY [0] allocated 19, used 19
2         PIN_FLD_CYCLE_DISCOUNT DECIMAL [0] 0
2         PIN_FLD_CYCLE_END_CYCLE DECIMAL [0] 0
2         PIN_FLD_CYCLE_END_T  TSTAMP [0] (0)
2         PIN_FLD_CYCLE_START_CYCLE DECIMAL [0] 0
2         PIN_FLD_CYCLE_START_T TSTAMP [0] (0)
2         PIN_FLD_PRODUCT_OBJ    POID [0] 0.0.0.1 /product 9518 2
2         PIN_FLD_PURCHASE_DISCOUNT DECIMAL [0] 0
2         PIN_FLD_PURCHASE_END_CYCLE DECIMAL [0] 0
2         PIN_FLD_PURCHASE_END_T TSTAMP [0] (0)
2         PIN_FLD_PURCHASE_START_CYCLE DECIMAL [0] 0
2         PIN_FLD_PURCHASE_START_T TSTAMP [0] (0)
2         PIN_FLD_QUANTITY     DECIMAL [0] 1
2         PIN_FLD_STATUS         ENUM [0] 1
2         PIN_FLD_STATUS_FLAGS    INT [0] 0
2         PIN_FLD_USAGE_DISCOUNT DECIMAL [0] 0
2         PIN_FLD_USAGE_END_CYCLE DECIMAL [0] 0
2         PIN_FLD_USAGE_END_T  TSTAMP [0] (0)
2         PIN_FLD_USAGE_START_CYCLE DECIMAL [0] 0
2         PIN_FLD_USAGE_START_T TSTAMP [0] (0)

Example:  Restricting the Search Results to Specific Fields:

Note that the PIN_FLD_RESULTS array on the input FLIST limits the results in the return FLIST.

# number of field entries allocated 20, used 5
0 PIN_FLD_POID           POID [0] 0.0.0.1 /search -1 0
0 PIN_FLD_RESULTS       ARRAY [*] allocated 20, used 2
1     PIN_FLD_POID           POID [0] NULL poid pointer
1     PIN_FLD_CREATED_T    TSTAMP [0] (0)
0 PIN_FLD_ARGS          ARRAY [1] allocated 20, used 1
1     PIN_FLD_NAME            STR [0] "Deal 1a - Measured Internet Service"
0 PIN_FLD_TEMPLATE        STR [0] "select X from /deal where F1 = V1 "
0 PIN_FLD_FLAGS           INT [0] 0
nap> xop 7 0 1
xop: opcode 7, flags 0
# number of field entries allocated 2, used 2
0 PIN_FLD_POID           POID [0] 0.0.0.1 /search -1 0
0 PIN_FLD_RESULTS       ARRAY [0] allocated 2, used 2
1     PIN_FLD_POID           POID [0] 0.0.0.1 /deal 8686 2
1     PIN_FLD_CREATED_T    TSTAMP [0] (976219881) 12/07/00 14:11:21

Example:  Non-Custom Search using /search template 201

This search uses a non-custom template.  The /search object with POID 201 is used.

# number of field entries allocated 20, used 4
0 PIN_FLD_POID           POID [0] 0.0.0.1 /search 201 0
0 PIN_FLD_RESULTS       ARRAY [*] allocated 20, used 3
1     PIN_FLD_POID           POID [0] NULL poid pointer
1     PIN_FLD_CREATED_T    TSTAMP [0] (0)
1     PIN_FLD_NAMEINFO      ARRAY [*] allocated 20, used 1
2         PIN_FLD_LAST_NAME       STR [0] NULL str ptr
0 PIN_FLD_ARGS          ARRAY [1] allocated 20, used 1
1     PIN_FLD_NAMEINFO      ARRAY [*] allocated 20, used 1
2         PIN_FLD_FIRST_NAME      STR [0] "Ronald"
0 PIN_FLD_FLAGS           INT [0] 0
nap> xop 7 0 1
xop: opcode 7, flags 0
# number of field entries allocated 2, used 2
0 PIN_FLD_POID           POID [0] 0.0.0.1 /search 201 0
0 PIN_FLD_RESULTS       ARRAY [0] allocated 3, used 3
1     PIN_FLD_POID           POID [0] 0.0.0.1 /account 25469857 53148
1     PIN_FLD_CREATED_T    TSTAMP [0] (1139417895) 02/08/06 10:58:15
1     PIN_FLD_NAMEINFO      ARRAY [1] allocated 1, used 1
2         PIN_FLD_LAST_NAME       STR [0] "Amedeo"

Example: Custom Account Search, Limit Result Set to 5 results

This result set is limited to the first 5 entries found.

# number of field entries allocated 20, used 5
0 PIN_FLD_POID           POID [0] 0.0.0.1 /search -1 0
0 PIN_FLD_RESULTS       ARRAY [5] allocated 20, used 3
1     PIN_FLD_POID           POID [0] NULL poid pointer
1     PIN_FLD_CREATED_T    TSTAMP [0] (0)
1     PIN_FLD_NAMEINFO      ARRAY [*] allocated 20, used 2
2         PIN_FLD_LAST_NAME       STR [0] NULL str ptr
2         PIN_FLD_FIRST_NAME      STR [0] NULL str ptr
0 PIN_FLD_ARGS          ARRAY [1] allocated 20, used 1
1     PIN_FLD_NAMEINFO      ARRAY [*] allocated 20, used 1
2         PIN_FLD_FIRST_NAME      STR [0] "%a%"
0 PIN_FLD_TEMPLATE        STR [0] "select X from /account where F1 like V1 "
0 PIN_FLD_FLAGS           INT [0] 0
nap> xop 7 0 1
xop: opcode 7, flags 0
# number of field entries allocated 6, used 6
0 PIN_FLD_POID           POID [0] 0.0.0.1 /search -1 0
0 PIN_FLD_RESULTS       ARRAY [0] allocated 3, used 3
1     PIN_FLD_POID           POID [0] 0.0.0.1 /account 35862893 19
1     PIN_FLD_CREATED_T    TSTAMP [0] (1268321292) 03/11/10 09:28:12
1     PIN_FLD_NAMEINFO      ARRAY [1] allocated 2, used 2
2         PIN_FLD_LAST_NAME       STR [0] "Funchesal"
2         PIN_FLD_FIRST_NAME      STR [0] "Debrah"
0 PIN_FLD_RESULTS       ARRAY [1] allocated 3, used 3
1     PIN_FLD_POID           POID [0] 0.0.0.1 /account 33265410 2065
1     PIN_FLD_CREATED_T    TSTAMP [0] (1238622641) 04/01/09 16:50:41
1     PIN_FLD_NAMEINFO      ARRAY [1] allocated 2, used 2
2         PIN_FLD_LAST_NAME       STR [0] "Ogrizlo"
2         PIN_FLD_FIRST_NAME      STR [0] "Mike"
0 PIN_FLD_RESULTS       ARRAY [2] allocated 3, used 3
1     PIN_FLD_POID           POID [0] 0.0.0.1 /account 35856912 42
1     PIN_FLD_CREATED_T    TSTAMP [0] (1267800937) 03/05/10 08:55:37
1     PIN_FLD_NAMEINFO      ARRAY [1] allocated 2, used 2
2         PIN_FLD_LAST_NAME       STR [0] "Christens"
2         PIN_FLD_FIRST_NAME      STR [0] "Beaud"
0 PIN_FLD_RESULTS       ARRAY [3] allocated 3, used 3
1     PIN_FLD_POID           POID [0] 0.0.0.1 /account 28715619 15211
1     PIN_FLD_CREATED_T    TSTAMP [0] (1187360056) 08/17/07 09:14:16
1     PIN_FLD_NAMEINFO      ARRAY [1] allocated 2, used 2
2         PIN_FLD_LAST_NAME       STR [0] "Binchini"
2         PIN_FLD_FIRST_NAME      STR [0] "Ginal"
0 PIN_FLD_RESULTS       ARRAY [4] allocated 3, used 3
1     PIN_FLD_POID           POID [0] 0.0.0.1 /account 34456511 191
1     PIN_FLD_CREATED_T    TSTAMP [0] (1252009050) 09/03/09 15:17:30
1     PIN_FLD_NAMEINFO      ARRAY [1] allocated 2, used 2
2         PIN_FLD_LAST_NAME       STR [0] "Ggoi"
2         PIN_FLD_FIRST_NAME      STR [0] "Dhuriba"

In my next blog entry, i will illustrate how to encapsulate a search into a C function.

2 Comments »

 

Oracle BRM Blog Thread

March 2nd, 2010 by Allan Anderson • 2 Comments »

Hey everyone.  SSG Blogs about a number of topics and this thread is about Oracle BRM.

Welcome.  My name is Allan Anderson. I started doing BRM/Portal Infranet implementations for SSG in 1998. Back then, we did many implementations on Infranet versions 4 and 5 (and, of course, upgrades). In the “oughts” we roughed the dot-bomb years working on Infranet release 6 implementations and are currently working on projects that include both versions 6 and 7. I personally have worked on 9 different BRM implementations over the past 12 years, including FlashNet, US West, Intel Online Services, InterAccess, TrivNet, ATX, T-Mobile USA, Iridium Sattelite,  and Savvis.

My co-workers at SSG have an even more impressive array of credentials, as many did not take “vacations” from consulting as I did to work full-time at any particular company.

Much of my BRM/Infranet knowledge is due to their expertise and help over the years. In a similar fashion i try to share my knowledge with my SSG colleagues whenever possible or when they need help. This really isnt anything special about me personally, but rather the SSG culture of knowledge and solution sharing responsible for much of our success.

Over the course of the past few weeks, I have given much thought to which blog topics would be most beneficial. The blog will cover both basic and obscure BRM functionality and “features”. As this list of features has evolved over the years, i ask you to bear with me when BRM functionality changes from release to release.

The initial list of blog topics include the following:

  • De-Mystifying the FLIST
  • Understanding the BRM Data Model and Database Mapping
  • Writing a Simple Search Using testnap and C
  • Scripting using SQL and testnap (loading objects, calling op-codes, etc.)
  • Migrating Accounts from External Systems
  • Rating Custom Events
  • Billing and invoicing for Single Accounts
  • Partitioning Overview & Common Tasks

I expect many more topics to be added as I or my SSG colleagues can think of new ones.

So welcome! Hopefully you (or someone out there) will find this blog useful.

Blog #1: De-Mystifying the FLIST

So when i was considering writing a blog about BRM, FLISTS jumped into my mind as a requirement for for any in-depth understanding of BRM and its workings, especially if one wants to do development or customizations of any kind. So having said that:

What the Heck is an FLIST??!?

FLIST is short for “Field List”, and its official definition is: A dynamically built structure of Field-Value pairs.

Since this description is pretty broad, a more detailed description of an FLIST is:
• A dynamically built data structure that is made up of one or more fields
• Made up of Fields which are identified by a unique name, ID, and data type (see $PIN_HOME/include/pin_flds.h for a list of the out-of-box fields)
• Used by BRM to represent objects defined in the data dictionary, and stored in the BRM database
• Used by BRM to define input and output to functional operations called op-codes
• May be converted to a string for logging purposes

FLIST Building Blocks: BRM Fields & Data Types:

The field data types are static and defined by BRM version you are running (you can view the types by looking in $PIN_HOME/include/pcm.h):

STRING (PIN_FLDT_STRING)

Your typical garden-variety null-terminated string. The length of the string is only limited when you want to store this to the BRM database, in which case the length is limited by the field length in the data dictionary and the database table.
Example:

0 PIN_FLD_DESCR STR [0] "Field Description"

INTEGER (PIN_FLDT_INT)

A signed Integer. Used by BRM to represent whole numbers.
Example:

0 PIN_FLD_RESOURCE_ID INT [0] 840

DECIMAL (PIN_FLD_DECIMAL)

Used by BRM to represent numbers with any level of required precision. Amounts, Quantities, etc. In C, represented by pin_decimal_t data type. BigDecimal used in Java applications.
Example:

0 PIN_FLD_TOTAL_DUE DECIMAL [0] 9813.2

ENUMERATION (PIN_FLDT_ENUM)

Used to represent natural numbers. Unsigned integer.
Example:

0 PIN_FLD_BILL_TYPE ENUM [0] 10001

BUFFER (PIN_FLDT_BUF)

Represents a sequence of bytes, typically used for strings of very long length. Stored as a blob when stored in the BRM database.
Example:

0 PIN_FLD_BUFFER BUF [0] flag/size/offset 0x0 109 0 data:
x000000 3c3f786d6c2076657273696f6e3d2231 .
x000040 3e0a093c42494c4c5f4e4f3e42312d35 >..B1-5
x000050 37393134363c2f42494c4c5f4e4f3e0a 79146.
x000060 3c2f696e766f6963653e0a0000 ...

POID (PIN_FLDT_POID)

The POID is a special BRM datatype, and is used to identify a specific instance of a BRM object. A POID contains 4 sub-elements:
Database: The database number for the database in which the object is stored. Unsigned Integer Value.
Type: String value representing the BRM object type represented by the POID. “/account” and “/bill” are examples.
ID: Unique value identifying this particular instance of the object type.
Revision: Unsigned Integer value. Incremented every time an objects data is updated.
Example:

0 PIN_FLD_ACCOUNT_OBJ POID [0] 0.0.0.1 /account 85273 3467

TIMESTAMP (PIN_FLDT_TSTAMP)

Timestamps in BRM are represented by the time_t C data structure. They represent a time in UTC. This is basically a number representing the number of seconds since the epoch.
Example:

0 PIN_FLD_START_T TSTAMP [0] (1267430401) Mon Mar 01 00:00:01 2010

SUBSTRUCT (PIN_FLDT_SUBSTR)

Represents a pointer to another single FLIST.
Note: When displayed as a string, sub-flists in SUBSTRUCTS and ARRAYS are indented and have an incremented “level” (the number before the field name) for each field in the flist.
Example:

0 PIN_FLD_PRODUCT SUBSTRUCT [0] allocated 2, used 2
1 PIN_FLD_NODE_LOCATION STR [0] "portala01#11522/1#20070720-090519.558:portala01#11522/1#20070720-090519.558"

ARRAY (PIN_FLDT_ARRAY)

Represents a pointer to an indexed array of FLISTS. Each array element has an integer index used to fetch individual flists out of the array.

Example:

0 PIN_FLD_ARGS ARRAY [1] allocated 20, used 1
1    PIN_FLD_AR_BILL_OBJ POID [0] 0.0.0.1 /bill 35677761 0
0 PIN_FLD_ARGS ARRAY [2] allocated 20, used 1
1    PIN_FLD_AR_ACCOUNT_OBJ POID [0] 0.0.0.1 /account 85273 3462
0 PIN_FLD_ARGS ARRAY [3] allocated 20, used 1
1    PIN_FLD_EFFECTIVE_T TSTAMP [0] (1267430401) Mon Mar 01 00:00:01 2010

It is important to note the difference between FLISTS that represent acutal BRM domain objects stored in the database and those representing Op-Code API request and response FLISTs.

FLISTs Representing Database Objects:

FLISTs representing objects in the BRM domain have a fixed structure, defined by the data dictionary. All of the FLISTS in this category contain the PIN_FLD_POID field, which identifies the data stucture (via the BRM data dictionary) for the class (identified in the type field of the poid). All objects of a particular class will have the exact same fields associated with them, for the most part (fields defined as optional may or may not be present in an instance of any particular class). The fields that make up a particular object can be modified, but thats a subject for a different blog.
For Example, an /bill object has different fields than an /account object:

/bill:

0 PIN_FLD_POID POID [0] 0.0.0.1 /bill 35677761 4
0 PIN_FLD_CREATED_T TSTAMP [0] (1267511488) Mon Mar 01 22:31:28 2010
0 PIN_FLD_MOD_T TSTAMP [0] (1270155627) Thu Apr 01 14:00:27 2010
0 PIN_FLD_READ_ACCESS STR [0] "L"
0 PIN_FLD_WRITE_ACCESS STR [0] "L"
0 PIN_FLD_ACCOUNT_OBJ POID [0] 0.0.0.1 /account 85273 3462
0 PIN_FLD_ADJUSTED DECIMAL [0] 0
0 PIN_FLD_BILL_NO STR [0] "B1-579146"
0 PIN_FLD_CURRENCY INT [0] 840
0 PIN_FLD_CURRENCY_OPERATOR ENUM [0] 0
0 PIN_FLD_CURRENCY_RATE DECIMAL [0] 0
0 PIN_FLD_CURRENCY_SECONDARY INT [0] 0
0 PIN_FLD_CURRENT_TOTAL DECIMAL [0] 9813.2
0 PIN_FLD_DISPUTED DECIMAL [0] 0
0 PIN_FLD_DUE DECIMAL [0] 9813.2
0 PIN_FLD_DUE_T TSTAMP [0] (1272697200) Sat May 01 00:00:00 2010
0 PIN_FLD_END_T TSTAMP [0] (1270105200) Thu Apr 01 00:00:00 2010
0 PIN_FLD_FLAGS INT [0] 0
0 PIN_FLD_INVOICE_OBJ POID [0] 0.0.0.1 /invoice 35944328 0
0 PIN_FLD_NAME STR [0] "PIN Bill"
0 PIN_FLD_PARENT POID [0] 0.0.0.0 0 0
0 PIN_FLD_PREVIOUS_TOTAL DECIMAL [0] 19735.4
0 PIN_FLD_RECVD DECIMAL [0] 0
0 PIN_FLD_START_T TSTAMP [0] (1267430400) Mon Mar 01 00:00:00 2010
0 PIN_FLD_SUBORDS_TOTAL DECIMAL [0] 0
0 PIN_FLD_TOTAL_DUE DECIMAL [0] 9813.2
0 PIN_FLD_TRANSFERED DECIMAL [0] 0
0 PIN_FLD_WRITEOFF DECIMAL [0] 0

/account:

# number of field entries allocated 107, used 107
0 PIN_FLD_POID POID [0] 0.0.0.1 /account 85273 3467
0 PIN_FLD_CREATED_T TSTAMP [0] (986025600) Sat Mar 31 00:00:00 2001
0 PIN_FLD_MOD_T TSTAMP [0] (1270154072) Thu Apr 01 13:34:32 2010
0 PIN_FLD_READ_ACCESS STR [0] “L”
0 PIN_FLD_WRITE_ACCESS STR [0] “L”
0 PIN_FLD_AAC_ACCESS STR [0] “”
0 PIN_FLD_AAC_PACKAGE STR [0] “”
0 PIN_FLD_AAC_PROMO_CODE STR [0] “”
0 PIN_FLD_AAC_SERIAL_NUM STR [0] “”
0 PIN_FLD_AAC_SOURCE STR [0] “”
0 PIN_FLD_AAC_VENDOR STR [0] “”
0 PIN_FLD_ACCESS_CODE1 STR [0] “”
0 PIN_FLD_ACCESS_CODE2 STR [0] “”
0 PIN_FLD_ACCOUNT_NO STR [0] “084363″
0 PIN_FLD_ACCOUNT_TAG STR [0] “”
0 PIN_FLD_ACCOUNT_TYPE ENUM [0] 1
0 PIN_FLD_ACTG_CYCLE_DOM INT [0] 1
0 PIN_FLD_ACTG_FUTURE_T TSTAMP [0] (1275375600) Tue Jun 01 00:00:00 2010
0 PIN_FLD_ACTG_LAST_T TSTAMP [0] (1270105200) Thu Apr 01 00:00:00 2010
0 PIN_FLD_ACTG_NEXT_T TSTAMP [0] (1272697200) Sat May 01 00:00:00 2010
0 PIN_FLD_ACTG_TYPE ENUM [0] 1
0 PIN_FLD_ATTRIBUTE INT [0] 0
0 PIN_FLD_BILLING_STATE ENUM [0] 0
0 PIN_FLD_BILLING_STATUS ENUM [0] 0
0 PIN_FLD_BILLING_STATUS_FLAGS INT [0] 0
0 PIN_FLD_BILL_ACTGCYCLES_LEFT INT [0] 1
0 PIN_FLD_BILL_MODE STR [0] “”
0 PIN_FLD_BILL_OBJ POID [0] 0.0.0.1 /bill 35847949 0
0 PIN_FLD_BILL_TYPE ENUM [0] 10001
0 PIN_FLD_BILL_WHEN INT [0] 1
0 PIN_FLD_BRAND_OBJ POID [0] 0.0.0.1 /account 1 1000
0 PIN_FLD_BUSINESS_TYPE ENUM [0] 0
0 PIN_FLD_CLOSE_WHEN_T TSTAMP [0] (0)
0 PIN_FLD_CURRENCY INT [0] 840
0 PIN_FLD_CURRENCY_SECONDARY INT [0] 0
0 PIN_FLD_EFFECTIVE_T TSTAMP [0] (1257877737) Tue Nov 10 10:28:57 2009
0 PIN_FLD_EXEMPT_FROM_COLLECTIONS INT [0] 0
0 PIN_FLD_GL_SEGMENT STR [0] “.”
0 PIN_FLD_GROUP_OBJ POID [0] 0.0.0.0 0 0
0 PIN_FLD_INCORPORATED_FLAG ENUM [0] 0
0 PIN_FLD_INTERNAL_NOTES BUF [0] flag/size/offset 0×0 403 0 data:
x000140 3a30383a323720504d0d0a4361746567 :08:27 PM..Categ
x000150 6f72793a20412f522043726564697420 ory: A/R Credit
x000160 4163636f756e740d0a5b437573746f6d Account..[Custom
x000170 6572206e6f7420736174697366696564 er not satisfied
x000180 207769746820736572766963655d2039 with service] 9
x000190 390d0a 9..
0 PIN_FLD_ITEM_POID_LIST STR [0] “0.0.0.1|/item/misc 35844939 0″
0 PIN_FLD_LASTSTAT_CMNT STR [0] “”
0 PIN_FLD_LAST_BILL_OBJ POID [0] 0.0.0.1 /bill 35677761 0
0 PIN_FLD_LAST_BILL_T TSTAMP [0] (1270105200) Thu Apr 01 00:00:00 2010
0 PIN_FLD_LAST_STATUS_T TSTAMP [0] (1001339927) Mon Sep 24 06:58:47 2001
0 PIN_FLD_LINEAGE STR [0] “/0.0.0.1:85273/”
0 PIN_FLD_LOCALE STR [0] “en_US”
0 PIN_FLD_MERCHANT STR [0] “N/A”
0 PIN_FLD_NAME STR [0] “PIN Account Object”
0 PIN_FLD_NEXT_BILL_OBJ POID [0] 0.0.0.0 0 0
0 PIN_FLD_NEXT_BILL_T TSTAMP [0] (1272697200) Sat May 01 00:00:00 2010
0 PIN_FLD_NEXT_ITEM_POID_LIST STR [0] “”
0 PIN_FLD_PARENT POID [0] 0.0.0.0 0 0
0 PIN_FLD_PAYINFO_OBJ POID [0] 0.0.0.1 /payinfo/invoice 26198422 0
0 PIN_FLD_PENDING_RECV DECIMAL [0] 9813.2
0 PIN_FLD_RESIDENCE_FLAG ENUM [0] 1
0 PIN_FLD_SCENARIO_OBJ POID [0] 0.0.0.0 0 0
0 PIN_FLD_STATUS ENUM [0] 10100
0 PIN_FLD_STATUS_FLAGS INT [0] 0
0 PIN_FLD_TIMEZONE_ID STR [0] “”
0 PIN_FLD_VAT_CERT STR [0] “”
0 PIN_FLD_BALANCES ARRAY [840] allocated 8, used 8
1 PIN_FLD_CREDIT_FLOOR DECIMAL [0] NULL
1 PIN_FLD_CREDIT_LIMIT DECIMAL [0] NULL
1 PIN_FLD_CREDIT_THRESHOLDS INT [0] 0
1 PIN_FLD_CURRENT_BAL DECIMAL [0] 17530.08
1 PIN_FLD_FLAGS INT [0] 0
1 PIN_FLD_NEXT_BAL DECIMAL [0] 0
1 PIN_FLD_OPEN_BAL DECIMAL [0] 17530.08
1 PIN_FLD_RESERVED_AMOUNT DECIMAL [0] 0
0 PIN_FLD_NAMEINFO ARRAY [1] allocated 21, used 21
1 PIN_FLD_ADDRESS STR [0] “1475 Military Blvd”
1 PIN_FLD_CANON_COMPANY STR [0] “Xprint”
1 PIN_FLD_CANON_COUNTRY STR [0] “US”
1 PIN_FLD_CITY STR [0] “REDWOOD CITY”
1 PIN_FLD_COMPANY STR [0] “Company Name”
1 PIN_FLD_CONTACT_TYPE STR [0] “Billing”
1 PIN_FLD_COUNTRY STR [0] “USA”
1 PIN_FLD_EMAIL_ADDR STR [0] “nobody@nowhere.com”
1 PIN_FLD_FIRST_CANON STR [0] “accounts”
1 PIN_FLD_FIRST_NAME STR [0] “Accounts”
1 PIN_FLD_LAST_CANON STR [0] “payable”
1 PIN_FLD_LAST_NAME STR [0] “Payable”
1 PIN_FLD_MIDDLE_CANON STR [0] “”
1 PIN_FLD_MIDDLE_NAME STR [0] “”
1 PIN_FLD_SALUTATION STR [0] “”
1 PIN_FLD_SERVICE_OBJ POID [0] 0.0.0.0 0 0
1 PIN_FLD_STATE STR [0] “CA”
1 PIN_FLD_TITLE STR [0] “”
1 PIN_FLD_ZIP STR [0] “94063″
1 PIN_FLD_PHONES ARRAY [0] allocated 2, used 2
2 PIN_FLD_PHONE STR [0] “2145551212″
2 PIN_FLD_TYPE ENUM [0] 2
1 PIN_FLD_PHONES ARRAY [2] allocated 2, used 2
2 PIN_FLD_PHONE STR [0] “N/A”
2 PIN_FLD_TYPE ENUM [0] 2
0 PIN_FLD_PRODUCTS ARRAY [13] allocated 32, used 32
1 PIN_FLD_CREATED_T TSTAMP [0] (986112000) Sun Apr 01 00:00:00 2001
1 PIN_FLD_CYCLE_DISCOUNT DECIMAL [0] 0
1 PIN_FLD_CYCLE_DISC_AMT DECIMAL [0] 0
1 PIN_FLD_CYCLE_END_T TSTAMP [0] (0)
1 PIN_FLD_CYCLE_FEE_AMT DECIMAL [0] 0
1 PIN_FLD_CYCLE_FEE_FLAGS INT [0] 3
1 PIN_FLD_CYCLE_START_T TSTAMP [0] (986112000) Sun Apr 01 00:00:00 2001
1 PIN_FLD_DEAL_OBJ POID [0] 0.0.0.1 /deal 142006 2
1 PIN_FLD_DESCR STR [0] “1-BMX323″
1 PIN_FLD_FLAGS INT [0] 3
1 PIN_FLD_LAST_MODIFIED_T TSTAMP [0] (0)
1 PIN_FLD_MMC_END_T TSTAMP [0] (992835668) Sun Jun 17 20:41:08 2001
1 PIN_FLD_MMC_START_T TSTAMP [0] (992835668) Sun Jun 17 20:41:08 2001
1 PIN_FLD_MMC_TYPE INT [0] 0
1 PIN_FLD_NODE_LOCATION STR [0] “10333199:10330639″
1 PIN_FLD_PLAN_OBJ POID [0] 0.0.0.0 0 0
1 PIN_FLD_PRODUCT_OBJ POID [0] 0.0.0.1 /product 142012 6
1 PIN_FLD_PURCHASE_DISCOUNT DECIMAL [0] 0
1 PIN_FLD_PURCHASE_DISC_AMT DECIMAL [0] 0
1 PIN_FLD_PURCHASE_END_T TSTAMP [0] (0)
1 PIN_FLD_PURCHASE_FEE_AMT DECIMAL [0] 0
1 PIN_FLD_PURCHASE_START_T TSTAMP [0] (986112000) Sun Apr 01 00:00:00 2001
1 PIN_FLD_QUANTITY DECIMAL [0] 1
1 PIN_FLD_SERVICE_OBJ POID [0] 0.0.0.1 /service/evolve 10332791 0
1 PIN_FLD_SMC_END_T TSTAMP [0] (1275375600) Tue Jun 01 00:00:00 2010
1 PIN_FLD_SMC_START_T TSTAMP [0] (1272697200) Sat May 01 00:00:00 2010
1 PIN_FLD_SPONSOR_OBJ POID [0] 0.0.0.0 0 0
1 PIN_FLD_STATUS ENUM [0] 1
1 PIN_FLD_STATUS_FLAGS INT [0] 55599999
1 PIN_FLD_USAGE_DISCOUNT DECIMAL [0] 0
1 PIN_FLD_USAGE_END_T TSTAMP [0] (0)
1 PIN_FLD_USAGE_START_T TSTAMP [0] (986112000) Sun Apr 01 00:00:00 2001

FLISTS Representing Op-Code Calls:

FLISTs are also used as a method of representing input and output to BRM Op-Codes. A given op-code will have a specific FLIST format (i.e. set of fields) defined for both input and output. Here are some examples of FLISTS used for Op-Code Calls:

Example:
PCM_OP_FIND_PROFILE Op-Code:
Input:

# number of field entries allocated 20, used 3
0 PIN_FLD_POID POID [0] 0.0.0.1 /account 85273 3467
0 PIN_FLD_ACCOUNT_OBJ POID [0] 0.0.0.1 /account 85273 3467
0 PIN_FLD_RESULTS ARRAY [0] allocated 20, used 1
1    MDS_FLD_CUST_INFO SUBSTRUCT [0] allocated 20, used 0

Output:

# number of field entries allocated 2, used 2
0 PIN_FLD_POID POID [0] 0.0.0.1 /account 85273 3467
0 PIN_FLD_RESULTS ARRAY [0] allocated 9, used 9
1    PIN_FLD_POID POID [0] 0.0.0.1 /profile/misc/customer_info 85273 1028
1    PIN_FLD_CREATED_T TSTAMP [0] (988756868) Tue May 01 15:41:08 2001
1    PIN_FLD_MOD_T TSTAMP [0] (1150839440) Tue Jun 20 14:37:20 2006
1    PIN_FLD_READ_ACCESS STR [0] "G"
1    PIN_FLD_WRITE_ACCESS STR [0] "S"
1    PIN_FLD_ACCOUNT_OBJ POID [0] 0.0.0.1 /account 85273 1000
1    PIN_FLD_NAME STR [0] "Converted Profile"
1    PIN_FLD_SERVICE_OBJ POID [0] 0.0.0.0 0 0
1    MDS_FLD_CUST_INFO SUBSTRUCT [0] allocated 33, used 33
2       PIN_FLD_EFFECTIVE_T TSTAMP [0] (0)
2       PIN_FLD_GEOCODE STR [0] ""
2       MVS_FLD_FINANCIAL_COMPANY_OBJ POID [0] 0.0.0.0 0 0
2       MDS_FLD_ACCT_ORG_ID STR [0] "MSC US"
2       MDS_FLD_ACCT_ROW_ID STR [0] "1+6CN+411"
2       MDS_FLD_ACCT_SALES_TYPE STR [0] "Web Hosting"
2       MDS_FLD_ACCT_TYPE STR [0] "00"
2       MDS_FLD_BILLING_ADDRESS_ID STR [0] "X1-1-1LB9"
2       MDS_FLD_BILLING_CONTACT_ROW_ID STR [0] "X5-1+7+0"
2       MDS_FLD_BILL_HANDLING_TYPE STR [0] "Normal Billing"
2       MDS_FLD_CUST_CLASS STR [0] ""
2       MDS_FLD_CUTOFF_T TSTAMP [0] (0)
2       MDS_FLD_DELIVERY_DEST STR [0] ""
2       MDS_FLD_DELIVERY_OPT STR [0] ""
2       MDS_FLD_DISC_GROUP STR [0] ""
2       MDS_FLD_DOM_RT_TBL STR [0] ""
2       MDS_FLD_EBILL_MEDIA STR [0] ""
2       MDS_FLD_EBILL_ROLL STR [0] ""
2       MDS_FLD_EVENT_RT_TBL STR [0] ""
2       MDS_FLD_IMG_RT_TBL STR [0] ""
2       MDS_FLD_IMG_RT_TBL_OLD STR [0] ""
2       MDS_FLD_INTL_RT_TBL STR [0] ""
2       MDS_FLD_INVOICE_COMMENTS STR [0] ""
2       MDS_FLD_INVOICE_TYPE STR [0] ""
2       MDS_FLD_INV_HOLD INT [0] 0
2       MDS_FLD_LATE_PAYMENT INT [0] 0
2       MDS_FLD_PRIMARY_ADDRESS_ROW_ID STR [0] "X5-1-1LB9"
2       MDS_FLD_PRINT_OPT STR [0] ""
2       MDS_FLD_REPORT_FREQ STR [0] ""
2       MDS_FLD_REPORT_ID STR [0] ""
2       MDS_FLD_SLSREP_FIRST_NAME STR [0] "ADMINISTRATOR"
2       MDS_FLD_SLSREP_LAST_NAME STR [0] "ADMINISTRATOR"
2       MDS_FLD_SLSREP_LOGIN STR [0] "SADMIN"

FLIST Manipulation using C:

We will start with C manipulation because BRM is written in C. Here are just a few examples of how to manipulate FLISTs and associated fields.

Some Local Variables for our examples:

/* Local Variables */
pin_flist_t *pFlist = NULL;
pin_flist_t *pSubFlist = NULL;
pin_flist_t *pSubAFlist = NULL;
pin_flist_t *pSubBFlist = NULL;

poid_t *pDummyPoid = NULL;
poid_t *pGetPoid = NULL;

char szMsg[256];
char *szGetMsg;

int iResourceId = 0;
int *pResourceId = NULL;
/* End Local Variables */

Creating an empty FLIST:

/* Create the FLIST using the PIN_FLIST_CREATE macro */
pFlist = PIN_FLIST_CREATE( pErrorBuffer );

Most FLIST manipulation macros will require the use of an pin error buffer (pin_errbuf_t *). This error buffer is set if problems occur during the operation.

Adding a POID field to an FLIST:

/* add POID to our newly created FLIST. Create a dummy poid to use. */
pDummyPoid = PIN_POID_CREATE( 1, "/search", (int64) -1, pErrorBuffer );
PIN_FLIST_FLD_SET( pFlist, PIN_FLD_POID, pDummyPOID, pErrorBuffer );

/* Now get the POID off of the FLIST for Logging */
pGetPoid = PIN_FLIST_FLD_GET( pFlist, PIN_FLD_POID, 0, pErrorBuffer );
PIN_ERR_LOG_POID( PIN_ERR_LEVEL_DEBUG, "The Poid Value is:", pGetPoid );

Adding a STRING field to an FLIST:

/* Add a string field to our FLIST */
sprintf( szMsg, "Hello, World!" );
PIN_FLIST_FLD_SET( pFlist, PIN_FLD_DESCR, szMsg, pErrorBuffer );

/* Now get the string off of the FLIST again */
szGetMsg = PIN_FLIST_FLD_GET( pFlist, PIN_FLD_DESCR, 0, pErrorBuffer );
PIN_ERR_LOG_MSG( PIN_ERR_LEVEL_DEBUG, szGetMsg );

Adding an INT field to an FLIST:

/* Add an integer field to our FLIST */
iResourceId = 840;
PIN_FLIST_FLD_SET( pFlist, PIN_FLD_RESOURCE_ID, &iResourceId, pErrorBuffer );

/* Now get the String and Print it. Always check pointers before de-referencing */
pResourceId = PIN_FLIST_FLD_GET( pFlist, PIN_FLD_RESOURCE_ID, 0, pErrorBuffer );
if( NULL != pResourceId ) {
sprintf( szMsg, "The Int Value Is: [%d]", *pResourceId );
PIN_ERR_LOG_MSG( PIN_ERR_LEVEL_DEBUG, szMsg );
}

Adding a SUBSTRUCT sub-flist to an FLIST:

/* Create an FLIST that we will store in the SUBSTRUCT */
pSubFlist = PIN_FLIST_CREATE( pErrorBuffer );
PIN_FLIST_FLD_SET( pSubFlist, PIN_FLD_RESOURCE_ID, &iResourceId, pErrorBuffer );

/* Put the SubFlist in the PIN_FLD_PRODUCT substruct */
/* By using the PUT we transfer the memory management of pSubFlist to pFlist */
/* We could have avoided the PUT by using the PIN_FLIST_SUBSTR_ADD() macro. Similar to the array example below */
pFlist = PIN_FLIST_CREATE( pErrorBuffer );
PIN_FLIST_SUBSTR_PUT( pFlist, pSubFlist, PIN_FLD_PRODUCT, pErrorBuffer );

PIN_ERR_LOG_FLIST( PIN_ERR_LEVEL_DEBUG, "FLIST With a SUBSTRUCT:", pFlist );

/* Frees the memory for both pSubFlist and pFlist */
PIN_FLIST_DESTROY_EX( &pFlist, NULL );

Adding Multiple Sub-FLISTs to an FLIST using an Array Field:

/* Create the top-level FLIST */
pFlist = PIN_FLIST_CREATE( pErrorBuffer );

/* Create an FLIST that we will store in the ARRAY */
/* Here we will use the PIN_FLIST_ELEM_ADD(), which keeps us from having to use PIN_FLIST_CREATE() and PIN_FLIST_ELEM_PUT() */
/* Put SubAFlist in Array Element 1, and SubBFlist in Array Element 2 */
iResourceId = 840;
pSubAFlist = PIN_FLIST_ELEM_ADD( pFlist, PIN_FLD_ARGS, 1, pErrorBuffer );
PIN_FLIST_FLD_SET( pSubAFlist, PIN_FLD_RESOURCE_ID, &iResourceId, pErrorBuffer );

iResourceId = 124;
pSubBFlist = PIN_FLIST_ELEM_ADD( pFlist, PIN_FLD_ARGS, 2, pErrorBuffer );
PIN_FLIST_FLD_SET( pSubBFlist, PIN_FLD_RESOURCE_ID, &iResourceId, pErrorBuffer );

PIN_ERR_LOG_FLIST( PIN_ERR_LEVEL_DEBUG, "FLIST with 2 Sub-Array Elements:", pFlist );

These are the most commonly used field types. If you need to use the others, there are out-of-box examples in policy code to look at ($PIN_HOME/src).

2 Comments »