Sunday, May 28, 2017

Pointers in AS400 (IBM i)

Hello Friends,

Pointers are one of the key features in AS400 RPG programming. If you are a beginner and just started to write some RPG code then it is good to understand the concept of pointers.

What is pointer?

Pointers are used to hold the memory address of a variable (just like how it used in C). This will become handy when we need to process larger size data.

Let us take a simple example:

Pointer can be declared using asterisk (*) symbol. We can assign this pointer to a variable using Based keyword. In the below example P_Data is based on pointer Ptr. This means, Ptr will hold any address and P_Data will display the content of that address.


We can see from above that, address of Var1 is assigned to Ptr. Now Var1 & P_Data points to same address. So if we change Var1 data, it will be reflected in P_Data.

Similarly, if we change P_Data value then it will be reflected in Var1 value.

Segmentation with pointers:

Using pointers we can split the large data into small chunks and access it.

Let us take below example:


Here Var1 is of length 100 but we are accessing the data by splitting into small chunks (of 10 length) using P_Data variable.

We initially assign address of Var1 into Ptr and then we increment the Ptr value by adding size of P_Data.

Output:



Do you know this trick?

Hopefully you might have used RPG calling another RPG using parameter. We would have noticed same variable used for both input & output. (i.e. if PGMA calls PGMB has parameter ABC, then I change the value of ABC in PGMB then it will reflect in PGMA automatically).

This is because; the two-way parameter is achieved using "shared memory".

When one program calls another, the only thing that’s passed between them is an address in the computer’s memory where the parameter starts. Nothing else is passed.

Look at the below example for better understanding.

TESTPGM à calls GETNAME it passes Name as parameter. But length of Name is 10 in TESTPGM. But we receive this value using *Entry Plist under FullName variable (of length 20) in GETNAME program. We assigned value “Mohammed Yusuf” and program returned the value to calling program (TESTPGM).

Now, if we display variable Name we get “Mohammed Y” alone. The remaining value gets assigned to Address variable (since both are under DS)


Output:

Name = “Mohammed Y”
Address = “usuf”

What happened here? When program “GETNAME” called, system passed the address of Name variable. And GETNAME program assigned the value “Mohammed Yusuf” in that address.

Now when TESTPGM receives it, Name variable can hold only 10 length so remaining text is present in Address variable. (because Name & Address are in single Data Structure so it forms continues memory allocation)

How to overcome this?

Instead of *Entry Plist, start using PI (Procedure Interface)
  1. It is similar to *Entry Plist (but better than that)
  2. It requires matching prototype to work
  3. Replacement of *Entry Plist in Free format

The program GENAME is changed to GETNAMEPR and uses PI to receive the parameter. The calling program TEST is changed with Prototype definition of GETNAMEPR.

With this in hand, if we try to call GETNAMEPR with variable Name it will throw error since length of Name is not matching with parameter length of Prototype.

Parameters & Prototype has many useful things in ILE programming. I will try to cover those in my upcoming posts.

Until then, Have fun…!!! Happy coding…!!!


Monday, May 8, 2017

XML parsing in AS400 (IBM-i) using XML-INTO

Hello Friends,

If you are new in working with XML in AS400 or just starting to do some XML parsing, this article will be useful to you.

XML-INTO is the op-code used to parse the XML document and retrieve the values directly into the variables in RPGLE.

Previously I saw many examples using DOM parser but it is complex for any beginners. But IBM introduced XML-INTO op-code and made the XML parsing much easier. Let us directly jump into syntax and examples.

Syntax:

xml-into <VariableName> %xml(<filename> : options)

There are couple of options which are considered while parsing the xml. We will see one by one.

Mostly the <variablename> will be a data structure which matches with the xml structure. 

Simple XML:


RPGLE:



Output:

Options in xml-into:

Case=any

In general XML tag names should match with RPG variables with case sensitive. But using case=any option we can eliminate it.

Doc=file

This tells the op-code that xml data source is coming from a file document. In this case, the first parameter of %XML function will be file name.

Allowmissing=yes

Sometimes if we are having missing fields in XML document

Allowextra=yes

Sometimes if we get extra tag in the XML (not defined in DS)

In other words, if u expect all the DS fields are mandatory in your XML you can give allowmissing=no and handle the exception and allowextra=no will not accept any extra tag to come in your xml.

In most cases, we use both as ‘yes’ and handle the exception in program.

Path=”string”

Using path option you can directly read any particular tag value. We will see it deeper in coming examples.

A complex XML:

Let us look at below example which has nested tags, attribute value and also repeating a particular tag number of times. 



Here we need to know how to define a nested data structure and how to find number of times a tag being repeated. Fortunately, xml-into offers an easy way to do that.

And trust me we can just parse all the values with single statement J

How to form nested Data Structure:



If you look closely, we have split the group of tags into separate DS and nested into main Customer DS using LikeDS keyword. The reason for CtInfo_T & Item_T is declared as Template but Order_T & OrdDet_T are declared as Qualified because, if we are going to have any nested DS then the parent DS should be declared as Qualified.

Take a note on DepartmentNumber. This exceeds normal variable length of 15 char while defining in RPGLE. So if we have variable length more than 15 char then we have to write the full name followed by three dots. Thus system will look for its declaration in next line. (in our case 2S 0)

Count_Item:

Do notice this variable Count_Item is an extra field apart from XML fields. When we need to parse multiple occurrence tags (in our case <item> tag) then we have to define a variable next to repeated tag so that system will automatically give us the number of repetition in this variable.

RPGLE code:



Please note on the countprefix option. We are saying the system to return the count of repetition under the variable has prefix “count_”

i.e. for item tag the count variable should be “count_item”

if we change “countprefix=cnt_” then in our DS, the variable should be “cnt_item”

here we go, we got all the values, and also the count_item has number of repetition as “3”.


With this in hand, we can very well do our program logic and proceed further.

One last example using path option:

Using path we can directly read any segment of xml. For example, I want to retrieve OrderNumber alone from the XML. Then,


Do note that if we are fetching value of a single tag directly then variable name to receive the value may not need to be the same xml tag name. (Here OrdNum is used).

Hope this post gives you enough idea to get start with xml-into method of parsing. It is really very useful as you can see it requires very minimal amount of coding. I will come with another topic soon. Until then…

Have fun..!!! Happy coding…!!!

Tuesday, May 2, 2017

AJAX & JSON with CGI Programming in IBM-I

Hello Friends,


In our last article we have seen how to use CGIDEV2 to update an external HTML from RPGLE and using that we were able to see some good looking outputs in browser. Now in this article we are going to see a step further and learn some basics about the following,
  1. What is AJAX
  2. What is JSON
  3. How to use JSON in AJAX in CGI programming

AJAX: Asynchronous JavaScript and XML

In simple term, this is a technique to update the web page content without reloading the page. Also  update includes, sending request to a server in background and based on response received we can update web page content.

E.g.: Let’s take our Order Inquiry example

We call ORDINQ CGI program from web which displays the order inquiry screen and gets input (say 123) and when we click submit, it redirect to ORDLISTCGI program with parameter as 123.


Here, after we click submit the page reloads with ORDLISTCGI program and HTML output is displayed with order details of order# 123.

Now, with AJAX we are going to send HTTP request and receive the response in the background and finally going to display the order list output in the same page without reloading it.

i.e.:


Step 1: Let's create new RPGLE CGI program

I have created a simple CGI program ORDHTML which returns order details in HTML format. It is pretty straight forward. If the order is found, then I am returning the values under <H3> tag.


If we want to test this, check the url http://as400/cgi/ordhtml?order=555 in browser


Now we want this piece of information to be updated in our main page (ORDINQAJAX) when we click submit button.

The good thing is our main page (ORDINQAJAX) is not necessarily being a CGI program. Instead it can be a plain HTML/JavaScript on your desktop.

ORDINQAJAX html:



What we have done here is, when we click Retrieve Order button, it calls loadDoc() function. This is forming the url by concatenating our input number value.

Once the url is formed, a XMLHttpRequest object is created using which we are requesting the response of ORDHTML url.

And finally the output available in responseText is replaced with the paragraph tag with id = “demo”

Input:



Output:



Take a note that the page is not reloaded and result is showed in the same ordinqajax.html

Here we have achieved AJAX and eliminated the dependency of input screen coming from AS400 CGI program. Since, our input screen is our HTML file, we can play with CSS and JavaScript to make it good looking and make is responsive.

But wait… what if we want to change the display format of order details? Currently it is always coming as <H3> header directly from ORDHTML page. Here is JSON comes into play…

JSON: JavaScript Object Notation

JSON is a Java Script object. I am not going in depth about it (because there is lot of tutorial in web). But I will show the basic by giving some examples.

Have a look at the below comparison of a sample XML and converted JSON format. 



JSON string enclosed by curly braces { and } and it is made up of “key” : “value” pair and colon ( “:”) to separate both. If any set is repeated, forms an array which enclosed by square brackets [ and ].

In our example, key “id” has value “901” & phones is an array and each phones contain keys “type” & “number”. Unlike XML, we don’t have any end tag here. So this really helps to reduce the file size.

We are quite familiar with XMLs in AS400/IBM-I but not much with JSON. But this JSON will become handy when dealing with web service or with CGI programming.

Since this is a JavaScript object, we can easily parse this and get the values inside JavaScript program.

E.g.: Once we assign this JSON string into a variable (say variable X) then we can start accessing the values using dot operator.


How to use JSON in AJAX:

The basic idea is we are going to return the json format of output to browser (instead of plain html content). When we receive this result in our HTML we can assign it to a variable in the JavaScript and can split the details and use it inside HTML.

E.g.: program ORDJSON which returns the response as JSON. Please note that I have changed my content-type as text/plain in this RPGLE.


As of now the code looks ugly. I shall come back about this later.

With this program in place,  we are already ready to see the json output in the browser.

http://as400/cgi/ordjson?order=555


Now let’s change our ORDINQAJAX html to parse this json and display output.

Modified ORDINQAJAX.html



We can see, the url is changed to point ordjson CGI program. The result in this.responseText is parsed into JSON using JSON.parse JavaScript method and stores the json object in obj variable.

Then it is just simple programming to use the values inside json. Here in this example, order number and date are just displayed and item details are added into rows of table (which has id=”detail”)

Let us see the input & output.

Input:



Output:



I hope you would have learnt something interesting and useful. Now a day, AS400 business logics (existing RPLGE) is being served as web services. If you have a deeper look, we have just created a RESTful web service based on order number input and it returns order detail as output JSON.

In the world of web programming, you can very well share this URL to your clients and they can use it accordingly to their needs.

What next?

Remember I have highlighted regarding ugly json formatting in RPGLE? You may think what will be the best possible way to create JSON in rpgle. Also if we need some complex JSON to be formed, concatenation is not at all a best way. Also how do we parse a JSON inside RPGLE?

For all these questions, I shall come back with answers in my next article. Until then...

Have Fun…!!! Happy Coding..!!!