Giter Site home page Giter Site logo

Comments (39)

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


long time fixed

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Matt Tuchfarber (Bitbucket: tuchfarber, GitHub: tuchfarber).


Well we would have NEVER found that one out on our own. Haha. And yet again the fix works great! Calling it with iDB2Call was actually even a little more performant in my testing. I appreciate the quick reply and helpful answer!

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


I forgot ... how do you fix this problem (if correct moving QTEMP mixed RPG access theory)??

option 1) Simple, switch from iLibCall to using iDB2Call. With this switch your called RPG programs will run in the same job as your ibm_db DB2 operations. Aka, half-modern RPG ExecSql and 'native access' and python ibm_db can share the same QTEMP again in the QSQSRVR job (*).

#!python

  conn = ibm_db.connect(database, user, password)
  itransport = iDB2Call(conn)

(*) Option 2) There is a second way using iLibCall or IDB2Call (or iRestCall). If you use python itoolkit 'ipc', there will be a third job 'XTOOLKIT' where XMLSERVICE will run routed from the QSQSRVR job. Actually using itoolkit 'ipc' would work from any of the transports iLibCall, iDB2Call, iRestCall, because all will be routed to the XTOOLKIT job. In fact, you could use all these access transports at the same time, because XMLSERVICE will synchronize the requests from all sources in the XTOOLKIT job (via semaphore lock). ANYWAY, any half modern RPG ExecSql and 'native' will share the common QTEMP in the 'XTOOLKIT' job. The only odd man out will be ibm_db which will be running DB2 in QSQSRVR job (not XTOOLKIT job).

#!python

ipc    (str): optional - XMLSERVICE xToolkit job route for *sbmjob ['/tmp/myunique42']

BTW -- Is your hat blowing off??? I told you this was complex ... but ... XMLSERVICE is well thought out to work in almost any configuration (no brag).

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


Hang on to your hat, it's going to get deep in here.

First, i don't think the issue is xmlservice or ibm_db.

Without data speculation ... working as designed 'anomaly' is likely 'server mode' default set by ibm_db.

Briefly, ibm_db issues a attribute request to DB2 to enter 'server mode'. This sets CLI (ODBC) used by python ibm_db into using proxy jobs for DB2 operations outside the running python job. When these 'proxy database' jobs are running attached QSQSRVR jobs you may see them in wrkactjob (do it quickly). Python ibm_db CLI 'server mode' technique allows ibm_db to handle multiple transactions, multiple connections with same or different profiles, etc. Bluntly, this is the only way to run a 'threaded' application web server/application handling multiple requests. Even non-threaded applications like PHP use this technique to allow multiple 'pooled' persistent connections.

So after the issue of conn = ibm_db.connect(), your python job is now in 'server mode' using a proxy QSQSRVR job for ALL 'SQL' style database work. Aka, your python program is no longer one job universe, all the database work is happening in the attached QSQSRVR job. More important, DB2 'SQL' access to QTEMP moved into the QSQSRVR job.

So, QTEMP moved to another job beyond python job. So what???

Python iLibCall() is an in-job call to your called RPG program. This means the QTEMP your RPG program will see is in the python job for 'native access'. However, IMPORTANT point now, any ExecSql style access will move to the QSQSRVR job allong with all the python ibm_db.

So, problem MAY actually be your called RPG program(s) using QTEMP. Specifically theorizing 'calling' collection (or single) half-modern RPG program(s) using both ExecSql (insert into QTEMP) and 'native access' (SETLL, CHAIN, etc., to read QTEMP). Except after ibm_db.connect, QTEMP used by RPG ExecSql moved to the QSQSRVR job. Meanwhile iLibCall RPG 'native access' is still looking in the python job QTEMP (old mother Hubbard QTEMP cupboard is bare). Yuour mixed ExecSql and 'native access' program is looking at the wrong QTEMP. Aka, you RPG half-modernised program(s) world just failed.

Of course, this is a theory, but it explains the facts (Sherlock Holmes).

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Matt Tuchfarber (Bitbucket: tuchfarber, GitHub: tuchfarber).


Sorry Tony, I replied to this on Tuesday but it must not have sent it seems. The new XMLToolkit is working! Thanks for getting it done so quickly, I really appreciate it. We are successfully getting results back from the service calls now. I did run into a bit of a weird snag today however, which may or may not be related to this same issue. It seems if I connect to the database with the ibm_db library, I can no longer make service calls with params by value correctly. I can, however, still make calls by reference just fine. See below:

Code being ran:

#!python

import os
os.environ["XMLSERVICE"] = "XMLSERVICE"

import ibm_db
from itoolkit import *
from itoolkit.lib.ilibcall import *

DB_NAME = '*LOCAL'
SQL_ATTR_DBC_SYS_NAMING = 10004

def getUser():
    itool = iToolKit()
    itransport = iLibCall()
    itool.add(iSrvPgm('curuser','HFASVUT','GetCurrentUser').addRet(iData('P0User','10a','')))
    itool.call(itransport)
    pgm_cur_user = itool.dict_out('curuser')
    print(pgm_cur_user)
    
def validHierarchy(level,value):
    itool = iToolKit()
    itransport = iLibCall()
    svg_pgm = iSrvPgm('valid_prod_hier','HFASVPR','IsProductHierarchyValueValid')
    param1 = iParm('p2',{'by':'val'})
    param1.add(iData('lpHierType','1a','M'))
    param2 = iParm('p3',{'by':'val'})
    param2.add(iData('lpHierValue','15a','LVA'))
    svg_pgm.add(param1)
    svg_pgm.add(param2)
    svg_pgm.addRet(iData('ret_val','1a',''))
    itool.add(svg_pgm)
    itool.call(itransport)
    valid_prod_hier = itool.dict_out("valid_prod_hier")
    print(valid_prod_hier)
 
validHierarchy("","")
validHierarchy("","")
validHierarchy("","")
getUser()
getUser()
getUser()
conn = ibm_db.connect(DB_NAME, None, None, {SQL_ATTR_DBC_SYS_NAMING: ibm_db.SQL_TRUE})
validHierarchy("","")
validHierarchy("","")
validHierarchy("","")
getUser()
getUser()
getUser()

Response:
python3 srvpgm_test.py

#!python

{'lpHierValue': 'LVA', 'ret_val': '1', 'success': '+++ success  HFASVPR IsProductHierarchyValueValid', 'lpHierType': 'M'}
{'lpHierValue': 'LVA', 'ret_val': '1', 'success': '+++ success  HFASVPR IsProductHierarchyValueValid', 'lpHierType': 'M'}
{'lpHierValue': 'LVA', 'ret_val': '1', 'success': '+++ success  HFASVPR IsProductHierarchyValueValid', 'lpHierType': 'M'}
{'P0User': '<REDACTED>', 'success': '+++ success  HFASVUT GetCurrentUser'}                                                  
{'P0User': '<REDACTED>', 'success': '+++ success  HFASVUT GetCurrentUser'}                                                  
{'P0User': '<REDACTED>', 'success': '+++ success  HFASVUT GetCurrentUser'}                                                  
{'lpHierValue': 'LVA', 'ret_val': '0', 'success': '+++ success  HFASVPR IsProductHierarchyValueValid', 'lpHierType': 'M'}
{'lpHierValue': 'LVA', 'ret_val': '0', 'success': '+++ success  HFASVPR IsProductHierarchyValueValid', 'lpHierType': 'M'}
{'lpHierValue': 'LVA', 'ret_val': '0', 'success': '+++ success  HFASVPR IsProductHierarchyValueValid', 'lpHierType': 'M'}
{'P0User': '<REDACTED>', 'success': '+++ success  HFASVUT GetCurrentUser'}                                                  
{'P0User': '<REDACTED>', 'success': '+++ success  HFASVUT GetCurrentUser'}                                                  
{'P0User': '<REDACTED>', 'success': '+++ success  HFASVUT GetCurrentUser'}    

The redacted username was the same in all calls, showing that pass by reference was working correctly. Any help would be very much appreciated.

Note: Immediately closing the connection to the database using ibm_db.close(conn) gives the same results as leaving it open.

Thanks,
Matt

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


Ok, give a try. Yips xmlservice.1.9.9.3 (latest).

Everything working by value except zoned decimal by value. I am not overly worried about zoned because in world of modernization, zoned decimal by value is unlikely. Aka, much more likely will be packed decimal, which works.

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


Almost made Friday. Apparently everything working except 'by value' zoned decimal. I need to talk to a colleague about register conventions 'by value' zoned decimal next week (zoned should not be a factor ... only size ... mmm). A few days, so far, not bad.

BTW -- I have not posted this latest new xmlservice anywhere yet.

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Matt Tuchfarber (Bitbucket: tuchfarber, GitHub: tuchfarber).


We're prepped to test the new version whenever it is ready. We are going to skip the current version, as you have found it to have issues still. Thanks again for all your help.

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


FYI -- I am still finding issues with 'value' when mixing various types. Plan for a newer version of SAVF. I will post message here when ready.

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


I am still working on XMLSERVICE 1.9.9.n+. Please expect a new SAVF today or tomorrow. Clarification for expectations. I am releasing xmlservice versions on YIPS because they should not effect other uses beyond 'value'. I want you to understand your task will be update xmlservice multiple times. This is what i mean by 'your help'. Again, i am trying to complete all 'value' changes by Friday. Thanks for the help.

The output of your test is unrevealing. The message "no output" is fairly useless. Great if you find an error between your python toolkit call and RPG interface (easy). However, if not, we may need to debug what is happening in XMLSERVICE. This is possible, but there are keyboard user logistics issues.

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Matt Tuchfarber (Bitbucket: tuchfarber, GitHub: tuchfarber).


We are currently in the process of getting the SAVF compiled and installed. We are also double checking the parameters of the service program (to make sure our param values are correct). I will update once we are able to test. For now here's

xml_out():

#!xml

<?xml version="1.0" ?><xmlservice>                                                                                               
<error>no output</error>                                                                                                         
<xmlhint><![CDATA[ pgm error="fast" func="GetProductHierarchy" name="HFASVPR" var="prod_hier"  parm by="val" io="both" var="p1"  
data type="10a" var="prFormat"/  /parm  parm by="val" io="both" var="p2"  data type="1a" var="prType"  ![CDATA[L]]  /data  /parm 
 parm by="val" io="both" var="p3"  data type="15a" var="prValue"  ![CDATA[UP]]  /data  /parm  parm io="both" var="p1"  data type=
"5a" var="prChannel"/  /parm  parm io="both" var="p2"  data type="50a" var="prChannelDesc"/  /parm  parm io="both" var="p3"  data
 type="5a" var="prMPG"/  /parm  parm io="both" var="p4"  data type="50a" var="prMPGDesc"/  /parm  parm io="both" var="p5"  data t
ype="5a" var="prClass"/  /parm  parm io="both" var="p6"  data type="50a" var="prClassDesc"/  /parm  parm io="both" var="p7"  data
 type="5a" var="prLine"/  /parm  parm io="both" var="p8"  data type="50a" var="prLineDesc"/  /parm  parm io="both" var="p9"  data
 type="15a" var="prPart"/  /parm  parm io="both" var="p10"  data type="30a" var="prPartDesc"/  /parm  /pgm ]]></xmlhint>         
</xmlservice>     

XML Toolkit version:

#!sh

version : XML Toolkit 1.9.2

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


Ok, i think i fixed pass by value for all types (not tested complete).

The new xmlservice can be downloaded.

SAVF source: YIPS latest (1.9.9.2)

Follow instructions on Yips link (installation). Use crtxml CL program to create into XMLSERVICE library. The use the python env var to call XMLSERVICE pgms/srvpgms in test XMLSERVICE library.

#!shell
===
default -- QXMLSERV shipped by PTF from IBM Rochester
===
bash-4.3$ python testdiag.py 
version   : XML Toolkit 1.9.2

===
XMLSERVICE - compile from download using the crtxml CL program
===
bash-4.3$ export XMLSERVICE=XMLSERVICE
bash-4.3$ python testdiag.py 
version   : XML Toolkit 1.9.9.2
bash-4.3$ 

GIT source: Bitbucket Gitt

Please continue working/testing. I think we may have it (or close).

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


So, back to your problem. We appear to have a Schrödinger's 'live cat'/'dead cat' dealing with your test. Obviously my test is working (not accounting witty data text returned, where you will have real data). I can not see the obvious difference between 'GetProductHierarchy' and 'GETSMART'. I am curious. Please consider posting the XML (if not confidential).

#!python

print(itool.xml_in())
itool.add(s1)
print(itool.xml_out())

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


Ok. I know what is wrong with at least the integers ... and ... probably all other primitives. 99.9% of PASE programs are c programs. AIX/PASE c programs expect 'natural alignment' for each data type, short or 5i0 - 2 byte align, int32 or 10i0- 4 byte aligned, int64 or 20i0 - 8 byte aligned, so on. The AIX xlc compiler will do this by default so that c programs run better on power hardware (most hardware). Multiples of by 2 for those of you playing the home read along game. Our RPG compiler, of course, everything is packed to 1-byte alignment (no align). Therefore code in XMLSERVICE 'value' is 'coded', but data is not correctly aligning for primitive types. Aka, we have to teach xmlservice about c programming 'natural alignment'.

(mmm ... so obvious now ... wonder how i missed when i fooled around with xmlservice to start).

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


BTW -- if you wish to change which XMLSERVICE used in iLibCall() there is an env var.

#!shell
===
default -- QXMLSERV shipped by PTF from IBM Rochester
===
bash-4.3$ python testdiag.py 
version   : XML Toolkit 1.9.2

===
XMLSERVICE - compile from download using the crtxml CL program
===
bash-4.3$ export XMLSERVICE=XMLSERVICE
bash-4.3$ python testdiag.py 
version   : XML Toolkit 1.9.9.1
bash-4.3$ 

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


As far as your test ... maybe add following print so we can see the xml.

#!python

print(itool.xml_in())
itool.add(s1)
print(itool.xml_out())

Also -- version toolkit is ok (same as me). However, we do not know which XMLSERVICE version you are using.

#!python

import os
from itoolkit import *
from itoolkit.lib.ilibcall import *
itransport = iLibCall()
itool = iToolKit()
myxml  = "<diag/>"
itool.add(iXml(myxml))
# print(itool.xml_in())
itool.call(itransport)
# print(itool.xml_out())
diag = itool.dict_out()
if 'version' in diag: 
  print ("version   : "+diag['version'])

#!shell

bash-4.3$ python testdiag.py 
version   : XML Toolkit 1.9.2

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


So, i did a little more testing ... and ... we stand partial working.

Working: aggregate 'value' type like 'character' (10a, 50A, etc.). In fact, likely applies to any data structure aggregate. (Aka, You probably get lucky with your data mix of character 'by val' and 'by ref').

Not work: primitive 'value' types like 3i0, 10i0, 20i0, 3u0, 10u0, 20u0, 12p2, 12s2, 8f, 4f, etc., are not fully implemented. I suspect these can be made to work as well, but require some time.

Do you need these other primitive types???

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Matt Tuchfarber (Bitbucket: tuchfarber, GitHub: tuchfarber).


I am also still in the process of finding more service programs that use a mix of value and reference. They are harder to find that expected.

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Matt Tuchfarber (Bitbucket: tuchfarber, GitHub: tuchfarber).


The new version isn't working for me still:

#!python

from itoolkit import *
from itoolkit.lib.ilibcall import *
itool = iToolKit()
itransport = iLibCall()

s1 = iSrvPgm('prod_hier','HFASVPR','GetProductHierarchy')
p1 = iParm('p1',{'by':'val'})
p1.add(iData('prFormat','10a',''))
p2 = iParm('p2',{'by':'val'})
p2.add(iData('prType','1a','L'))
p3 = iParm('p3',{'by':'val'})
p3.add(iData('prValue','15a','UP'))
s1.add(p1)
s1.add(p2)
s1.add(p3)
s1.addParm(iData('prChannel','5a',''))
s1.addParm(iData('prChannelDesc','50a',''))
s1.addParm(iData('prMPG','5a',''))
s1.addParm(iData('prMPGDesc','50a',''))
s1.addParm(iData('prClass','5a',''))
s1.addParm(iData('prClassDesc','50a',''))
s1.addParm(iData('prLine','5a',''))
s1.addParm(iData('prLineDesc','50a',''))
s1.addParm(iData('prPart','15a',''))
s1.addParm(iData('prPartDesc','30a',''))

itool.add(s1)
itool.call(itransport)
prod_hier = itool.dict_out('prod_hier')
print(prod_hier)

Output:

#!sh

   $                                                                                                                                
 > python3 srvpgm_test.py                                                                                                           
   {'prLine': '', 'success': '+++ success  HFASVPR GetProductHierarchy', 'prChannel': '', 'prClass': '', 'prChannelDesc': '', 'prMPG
   ': '', 'prClassDesc': '', 'prMPGDesc': '', 'prValue': 'UP', 'prType': 'L', 'prFormat': ' ', 'prPartDesc': '', 'prLineDesc': '', '
   prPart': ''}                                                                                                                     
   $              

Just to verify we are using the same version, these are my package versions:

#!sh

   $                         
 > pip3 freeze               
   bottle==0.12.8            
   flipflop==1.0             
   ibm-db==2.0.5.5           
   ibm-db-django==1.0.9.1    
   itoolkit==1.2             
   six==1.10.0               
   $         

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


Short version, 'value' syntax looks like following.

#!python

#       dcl-proc GetSmart export;
#       dcl-pi  *N;
#         p0Format char(10) Value;
#         p0Type char(1) Value;
#         p0Value char(15) Value;
#         p0Channel char(5);
#         p0ChannelDesc char(50);
#         p0MPG char(5);
#         p0MPGDesc char(50);
#         p0Class char(5);
#         p0ClassDesc char(50);
#         p0Line char(5);
#         p0LineDesc char(50);
#         p0Part char(15);
#         p0PartDesc char(30);
#       end-pi;
s1 = iSrvPgm('getsmart','TESTZSRV','GETSMART')
p1 = iParm('p1',{'by':'val'})
p1.add(iData('p0Format','10a',''))
p2 = iParm('p2',{'by':'val'})
p2.add(iData('p0Type','1a',''))
p3 = iParm('p3',{'by':'val'})
p3.add(iData('p0Value','15a',''))
s1.add(p1)
s1.add(p2)
s1.add(p3)
s1.addParm(iData('p0Channel','5a',''))
s1.addParm(iData('p0ChannelDesc','50a',''))
s1.addParm(iData('p0MPG','5a',''))
s1.addParm(iData('p0MPGDesc','50a',''))
s1.addParm(iData('p0Class','5a',''))
s1.addParm(iData('p0ClassDesc','50a',''))
s1.addParm(iData('p0Line','5a',''))
s1.addParm(iData('p0LineDesc','50a',''))
s1.addParm(iData('p0Part','15a',''))
s1.addParm(iData('p0PartDesc','30a',''))

BTW -- Most people demand idea of parameter 'container of data' to remain abstract (not an object iParm). This is of course faulty logic, because 'contained' iData changes meaning with context inside iDs, iRet and iParm (all containers). Aka, 'value' has no meaning in iDs or iRet. Only when iParm contains iData does the attribute 'value' or 'const' have meaning. Some folks get really exercised about this logic. Anyway, pgm.addParm(iData or iDs) allows a verb representation of an action that adds a parameter object to the PGM/SRVPGM containing iData or iDS (aggregate of iData). All in all, we may have to add another verb(ish) addParmByVal(iData or iDs) to keep the 'no parameter' pitch forks at bay.

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


Ok. This already works. We just did not use the correct python syntax. I forgot addParm(iData) was a convenience function for people. We would need to add a new method like addParmByValue(iData).

Bottom line: Possible 'value' already works (i must have fixed it, then forgot).

#!shell

bash-4.3$ python testval2.py 
+++ success CHGLIBL LIBL(XMLSERVICE)
 
 
 
ch1
Great SyFy
4mpg
i dunno mpg
low
ye haw
lin5
line man county
part1
hairy frog

#!python

import os
from itoolkit import *
from itoolkit.lib.ilibcall import *

itransport = iLibCall()

itool = iToolKit()
itool.add(iCmd('chglibl', 'CHGLIBL LIBL(XMLSERVICE)'))
#       dcl-proc GetSmart export;
#       dcl-pi  *N;
#         p0Format char(10) Value;
#         p0Type char(1) Value;
#         p0Value char(15) Value;
#         p0Channel char(5);
#         p0ChannelDesc char(50);
#         p0MPG char(5);
#         p0MPGDesc char(50);
#         p0Class char(5);
#         p0ClassDesc char(50);
#         p0Line char(5);
#         p0LineDesc char(50);
#         p0Part char(15);
#         p0PartDesc char(30);
#       end-pi;
s1 = iSrvPgm('getsmart','TESTZSRV','GETSMART')
p1 = iParm('p1',{'by':'val'})
p1.add(iData('p0Format','10a',''))
p2 = iParm('p2',{'by':'val'})
p2.add(iData('p0Type','1a',''))
p3 = iParm('p3',{'by':'val'})
p3.add(iData('p0Value','15a',''))
s1.add(p1)
s1.add(p2)
s1.add(p3)
s1.addParm(iData('p0Channel','5a',''))
s1.addParm(iData('p0ChannelDesc','50a',''))
s1.addParm(iData('p0MPG','5a',''))
s1.addParm(iData('p0MPGDesc','50a',''))
s1.addParm(iData('p0Class','5a',''))
s1.addParm(iData('p0ClassDesc','50a',''))
s1.addParm(iData('p0Line','5a',''))
s1.addParm(iData('p0LineDesc','50a',''))
s1.addParm(iData('p0Part','15a',''))
s1.addParm(iData('p0PartDesc','30a',''))

itool.add(s1)

itool.call(itransport)
chglibl = itool.dict_out('chglibl')
getsmart = itool.dict_out('getsmart')
print(chglibl['success'])
# print(getsmart)
# print(itool.xml_in())
# print(itool.xml_out())
if 'success' in getsmart:
  print(getsmart['p0Format'])
  print(getsmart['p0Type'])
  print(getsmart['p0Value'])
  print(getsmart['p0Channel'])
  print(getsmart['p0ChannelDesc'])
  print(getsmart['p0MPG'])
  print(getsmart['p0MPGDesc'])
  print(getsmart['p0Class'])
  print(getsmart['p0ClassDesc'])
  print(getsmart['p0Line'])
  print(getsmart['p0LineDesc'])
  print(getsmart['p0Part'])
  print(getsmart['p0PartDesc'])

#!shell

       dcl-proc GetSmart export;
       dcl-pi  *N;
         p0Format char(10) Value;
         p0Type char(1) Value;
         p0Value char(15) Value;
         p0Channel char(5);
         p0ChannelDesc char(50);
         p0MPG char(5);
         p0MPGDesc char(50);
         p0Class char(5);
         p0ClassDesc char(50);
         p0Line char(5);
         p0LineDesc char(50);
         p0Part char(15);
         p0PartDesc char(30);
       end-pi;
         p0Format = 'i be fmt';
         p0Type = '9';
         p0Value = 'i be value';
         p0Channel = 'ch1';
         p0ChannelDesc = 'Great SyFy';
         p0MPG = '4mpg';
         p0MPGDesc = 'i dunno mpg';
         p0Class = 'low';
         p0ClassDesc = 'ye haw';
         p0Line = 'lin5';
         p0LineDesc = 'line man county';
         p0Part = 'part1';
         p0PartDesc = 'hairy frog';
       end-proc;

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


DO you have a few more parameter layouts that mix 'value' with 'ref' like GetProductHierarchy? If yes, please post a few (*). I will try to fix up value (if possible), and post a new version on yips for our experiment (i will add link).

(*) Reminder: This is a public forum, so do not post business confidential information (everyone can see).

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Matt Tuchfarber (Bitbucket: tuchfarber, GitHub: tuchfarber).


I think we'd be available to test out some fixes, as waiting until beginning of summer for the new service isn't preferable. What do you need from me?

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


Almost worked ... many pointer locations are good following values, but pointing wrong place. So, looks like we can fix this, but take a while to test it out. What would you like to do?

(Reminder ... half day invested so far ... could be working before Friday if you want to try)

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


Yes ... i will take a quick look ... after 'value(s)' probably misaligned pointers off quadword (guess)... we are actually closer than i thought.

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


Nope ... mixing ref and val did not work ...

(incorrect python syntax removed -- see last entry)

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Matt Tuchfarber (Bitbucket: tuchfarber, GitHub: tuchfarber).


My attempt wasn't quite as successful:

#!python

import os
from itoolkit import *
from itoolkit.lib.ilibcall import *
itool = iToolKit()
itransport = iLibCall()

itool.add(iCmd('chglibl', 'CHGLIBL LIBL(XMLSERVICE)'))

itool.add(iSrvPgm('unimportant_name','HFASVPR','GetProductHierarchy',{"error":"on"})
    .addParm(iData('prFormat','10a','',{'by':'val'}))
    .addParm(iData('prType','1a','M',{'by':'val'}))
    .addParm(iData('prValue','15a','LVA',{'by':'val'}))
    .addParm(iData('prChannel','5a',''))
    .addParm(iData('prChannelDesc','50a',''))
    .addParm(iData('prMPG','5a',''))
    .addParm(iData('prMPGDesc','50a',''))
    .addParm(iData('prClass','5a',''))
    .addParm(iData('prClassDesc','50a',''))
    .addParm(iData('prLine','5a',''))
    .addParm(iData('prLineDesc','50a',''))
    .addParm(iData('prPart','15a',''))
    .addParm(iData('prPartDesc','30a',''))
    .addRet(iData('ret_val','1a',''))
)

itool.call(itransport)

chglibl = itool.dict_out('chglibl')
unimportant_name = itool.dict_out('unimportant_name')
print(chglibl)
print(unimportant_name['success'])

if 'success' in unimportant_name:
    print(unimportant_name)

Output:

#!sh

   $                                                                                                                                
 > python3 srvpgm_test.py                                                                                                           
   {'jobuser': 'HQPGMXT', 'dftccsid': '37', 'error1': '202', 'jobipcskey': 'FFFFFFFF', 'curuser': 'HQPGMXT', 'jobnbr': '632888', 'pa
   seccsid': '819', 'jobname': 'QP0ZSPWP', 'ccsid': '65535', 'error': '*** error CHGLIBL LIBL(XMLSERVICE)', 'jobipc': '*na', 'xmlhin
   t': 'CHGLIBL LIBL(XMLSERVICE)', 'version': 'XML Toolkit 1.9.2', 'xmlhint2': 'CHGLIBL LIBL(XMLSERVICE)', 'syslibl': 'ALTQSYS DMSDA
   TA QSYS QSYS2 QHLPSYS QUSRSYS RBTSYSLIB', 'usrlibl': 'QTEMP HQPGMXT QGPL HFADTAMC HFASYSMAN HFASYS HFASECURE UTLFIL UTLPRD HFACGI
   MC HFACGIGB HFACGIGC HFAOBJMC HFAOBJGB HFAOBJGC HFASRCMC HFASRCGB HFASRCGC HFAOBJ HFASRCGIMC HFASRCGIGB HFASRCGIGC ACMSCTL AVPFIL
    GLDBFMC G3X4DTA EASYMENU'}                                                                                                      
   +++ success  HFASVPR GetProductHierarchy                                                                                         
   {'prChannel': '', 'prClass': '', 'prType': 'M', 'prLine': '', 'prChannelDesc': '', 'prClassDesc': '', 'prPartDesc': '', 'prPart':
    '', 'prFormat': '', 'prLineDesc': '', 'prValue': 'LVA', 'success': '+++ success  HFASVPR GetProductHierarchy', 'prMPGDesc': '', 
   'prMPG': '', 'ret_val': '0'}                                                                                                     
   $                  

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


(incorrect python syntax removed -- see last entry)

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


Ok ... wonders ... looks like it worked from python as well ...

(incorrect python syntax removed -- see last entry)

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Matt Tuchfarber (Bitbucket: tuchfarber, GitHub: tuchfarber).


Nice! Just to be clear (sorry, I'm a Python dev, not an RPG dev), all that needed to be done was tack on a by="val" to the XML and it works? I'm going to be calling these programs from Python so in order to make this work I would need to

  1. Build the XML manually to include the by="val"
  2. Call into the XMLSERVICE directly with the XML created (therefore skipping the itoolkit entirely)

Is that correct? Or is there a way I can use this in addition to the itoolkit, so I can use the nice features like dict_out?

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


Well ... Jimmy Cricket ... this simple test worked (by value) with no modifications to xmlservice 1.9.9.1. The luck of the Irish, but i am Norwegian.

#!shell

     H AlwNull(*UsrCtl)

      /copy test_h         

       // ****************************************************          
       // xmlservice/xmlstoredp SRVPGM
       // ****************************************************          
       dcl-pr runClient ind;
         pIPCSP char(1024);
         pCtl char(1024);
         pIClob pointer;
         szIClob int(10);
         pOClob pointer;
         szOClob int(10);
       end-pr;


       // ****************************************************          
       // TESTPGM 
       // ****************************************************          
       dcl-pr Main extpgm;
       end-pr;

       // ****************************************************          
       // main(): Control flow
       // ****************************************************          
       dcl-pi Main;
       end-pi;

       // ****************************************************          
       // tests
       // ****************************************************          
       dcl-s i int(10) inz(0);

       testboom();
       testval1();
       testval2();
       testval4();
       testval5();
       testval6();

       return;

       // ****************************************************          
       // interface to old xmlservice
       // ****************************************************          
       dcl-proc xjRun;
       dcl-pi *N;
         xjIn pointer value;
         xjOut pointer value;
         xjInSz int(10) value;
         xjOutSz int(10) value;
       end-pi;

       dcl-s ipc char(1024) inz(*BLANKS);
       dcl-s ctl char(1024) inz(*BLANKS);

       ipc = '*na';
       ctl = '*here';

       runClient(ipc:ctl:xjIn:xjInSz:xjOut:xjOutSz);

       end-proc;

       // ****************************************************          
       // test: TESTZSRV.TESTBOOM
       // ****************************************************          
       dcl-proc testboom;
       dcl-pi *N;
       end-pi;
       dcl-s xjInData char(4096) inz(*BLANKS);
       dcl-s xjOutData char(4096) inz(*BLANKS);
       dcl-s xjIn pointer inz(%addr(xjInData));
       dcl-s xjOut pointer inz(%addr(xjOutData));

       xjInData = 
         '<?xml version="1.0"?>'
       + '<myscript>'
       + '<pgm name="TESTZSRV" lib="'+TEST_LIB+'" func="TESTBOOM">'
       + ' <return>'
       + '   <data type="10i0">3</data>'
       + ' </return>'
       + '</pgm>'
       + '</myscript>'
       + x'00';

       xjRun(xjIn:xjOut:4096:4096);

       end-proc;

       // ****************************************************          
       // test: TESTZSRV.TESTVAL1
       // ****************************************************          
       dcl-proc testval1;
       dcl-pi *N;
       end-pi;
       dcl-s xjInData char(4096) inz(*BLANKS);
       dcl-s xjOutData char(4096) inz(*BLANKS);
       dcl-s xjIn pointer inz(%addr(xjInData));
       dcl-s xjOut pointer inz(%addr(xjOutData));

       xjInData = 
         '<?xml version="1.0"?>'
       + '<myscript>'
       + '<pgm name="TESTZSRV" lib="'+TEST_LIB+'" func="TESTVAL1">'
       + ' <parm  io="both" by="val">'
       + '   <data type="10i0">3</data>'
       + ' </parm>'
       + ' <return>'
       + '   <data type="10i0">3</data>'
       + ' </return>'
       + '</pgm>'
       + '</myscript>'
       + x'00';

       xjRun(xjIn:xjOut:4096:4096);

       end-proc;

       // ****************************************************          
       // test: TESTZSRV.TESTVAL2
       // ****************************************************          
       dcl-proc testval2;
       dcl-pi *N;
       end-pi;
       dcl-s xjInData char(4096) inz(*BLANKS);
       dcl-s xjOutData char(4096) inz(*BLANKS);
       dcl-s xjIn pointer inz(%addr(xjInData));
       dcl-s xjOut pointer inz(%addr(xjOutData));

       xjInData = 
         '<?xml version="1.0"?>'
       + '<myscript>'
       + '<pgm name="TESTZSRV" lib="'+TEST_LIB+'" func="TESTVAL2">'
       + ' <parm  io="both" by="val">'
       + '   <data type="10i0">3</data>'
       + ' </parm>'
       + ' <parm  io="both" by="val">'
       + '   <data type="20i0">4</data>'
       + ' </parm>'
       + ' <return>'
       + '   <data type="20i0">3</data>'
       + ' </return>'
       + '</pgm>'
       + '</myscript>'
       + x'00';

       xjRun(xjIn:xjOut:4096:4096);

       end-proc;


       // ****************************************************          
       // test: TESTZSRV.TESTVAL4
       // ****************************************************          
       dcl-proc testval4;
       dcl-pi *N;
       end-pi;
       dcl-s xjInData char(4096) inz(*BLANKS);
       dcl-s xjOutData char(4096) inz(*BLANKS);
       dcl-s xjIn pointer inz(%addr(xjInData));
       dcl-s xjOut pointer inz(%addr(xjOutData));

       xjInData = 
         '<?xml version="1.0"?>'
       + '<myscript>'
       + '<pgm name="TESTZSRV" lib="'+TEST_LIB+'" func="TESTVAL4">'
       + ' <parm  io="both" by="val">'
       + '   <data type="3i0">4</data>'
       + ' </parm>'
       + ' <parm  io="both" by="val">'
       + '   <data type="5i0">5</data>'
       + ' </parm>'
       + ' <parm  io="both" by="val">'
       + '   <data type="10i0">6</data>'
       + ' </parm>'
       + ' <parm  io="both" by="val">'
       + '   <data type="20i0">7</data>'
       + ' </parm>'
       + ' <return>'
       + '   <data type="16a">olive</data>'
       + ' </return>'
       + '</pgm>'
       + '</myscript>'
       + x'00';

       xjRun(xjIn:xjOut:4096:4096);

       end-proc;


       // ****************************************************          
       // test: TESTZSRV.TESTVAL5
       // ****************************************************          
       dcl-proc testval5;
       dcl-pi *N;
       end-pi;
       dcl-s xjInData char(4096) inz(*BLANKS);
       dcl-s xjOutData char(4096) inz(*BLANKS);
       dcl-s xjIn pointer inz(%addr(xjInData));
       dcl-s xjOut pointer inz(%addr(xjOutData));

       xjInData = 
         '<?xml version="1.0"?>'
       + '<myscript>'
       + '<pgm name="TESTZSRV" lib="'+TEST_LIB+'" func="TESTVAL5">'
       + ' <parm  io="both">'
       + '   <data type="3i0">4</data>'
       + ' </parm>'
       + ' <parm  io="both">'
       + '   <data type="5i0">5</data>'
       + ' </parm>'
       + ' <parm  io="both">'
       + '   <data type="10i0">6</data>'
       + ' </parm>'
       + ' <parm  io="both">'
       + '   <data type="20i0">7</data>'
       + ' </parm>'
       + ' <return>'
       + '   <data type="20i0">3</data>'
       + ' </return>'
       + '</pgm>'
       + '</myscript>'
       + x'00';

       xjRun(xjIn:xjOut:4096:4096);

       end-proc;


       // ****************************************************          
       // test: TESTZSRV.TESTVAL6
       // ****************************************************          
       dcl-proc testval6;
       dcl-pi *N;
       end-pi;
       dcl-s xjInData char(4096) inz(*BLANKS);
       dcl-s xjOutData char(4096) inz(*BLANKS);
       dcl-s xjIn pointer inz(%addr(xjInData));
       dcl-s xjOut pointer inz(%addr(xjOutData));

       xjInData = 
         '<?xml version="1.0"?>'
       + '<myscript>'
       + '<pgm name="TESTZSRV" lib="'+TEST_LIB+'" func="TESTVAL6">'
       + ' <return>'
       + '   <data type="16a">frog</data>'
       + ' </return>'
       + '</pgm>'
       + '</myscript>'
       + x'00';

       xjRun(xjIn:xjOut:4096:4096);

       end-proc;

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


Well ... i have two answers ...

  1. xjservice (new) -- targeting around common ... bit aggressive ... may slip into summer. This technology is completely different than xmlservice. Aka, in fact, so far no PASE utilization at all ... to speed things up.

  2. xmlservice (old) -- I did put a place holder in for pass-by value. Did not really test the idea as very few 'modernized' *SRVPGMs where using 'value' keyword. Blah Blah ... we should all be using 100% free form with dcl-s, dcl-ds, etc. (i am in xjservice).

Proposal. If you are interested in being a 'test subject' (think hamster wheel) ... it is possible to implement by value in the old technology. Do you want to work together for a week or so and get it working???

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Matt Tuchfarber (Bitbucket: tuchfarber, GitHub: tuchfarber).


Ah, that you for that. I missed that part of the documentation. That would explain it. Do we have an ETA for xjservice? Just a general idea of year or quarter so we can make a better decision about moving forward from here. Thanks.

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


You will need the next version of xmlservice 2 for pass by value support. Name is xjservice, as it supports both json and xml.

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


Yes. Expected failure. XMLSERVICE does not support pass by value.

#!python

/01  DGetProductHierarchy...
/01  D                 Pi             1n
/01  D  p0Format                     10a   Value ... unsupported
/01  D  p0Type                        1a   Value ... unsupported
/01  D  p0Value                      15a   Value ... unsupported
/01  D  p0Channel                     5a ... ok, pass by reference

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Matt Tuchfarber (Bitbucket: tuchfarber, GitHub: tuchfarber).


Thanks for the clarification on the iParm. As for the code we are trying to run, I have included the relevant sources below.

Script we are testing with:

#!python

from itoolkit import *
from itoolkit.lib.ilibcall import *
itool = iToolKit()
itransport = iLibCall()
itool.add(iSrvPgm('unimportant_name','HFASVPR','GetProductHierarchy',{"error":"on"})
    .addParm(iData('prFormat','10a',''))
    .addParm(iData('prType','1a','L'))
    .addParm(iData('prValue','15a','UP'))
    .addParm(iData('prChannel','5a',''))
    .addParm(iData('prChannelDesc','50a',''))
    .addParm(iData('prMPG','5a',''))
    .addParm(iData('prMPGDesc','50a',''))
    .addParm(iData('prClass','5a',''))
    .addParm(iData('prClassDesc','50a',''))
    .addParm(iData('prLine','5a',''))
    .addParm(iData('prLineDesc','50a',''))
    .addParm(iData('prPart','15a',''))
    .addParm(iData('prPartDesc','30a',''))
    .addRet(iData('ret_val','1a',''))
)
itool.call(itransport)
unimportant_name = itool.dict_out('unimportant_name')
print(unimportant_name)

Response from script:

#!python

{
    'prMPGDesc': '', 
    'prClassDesc': '', 
    'prMPG': '', 
    'prPart': '', 
    'prLineDesc': '', 
    'success': '+++ success  HFASVPR GetProductHierarchy', 
    'prChannel': '', 
    'prPartDesc': '', 
    'ret_val': '0', 
    'prFormat': '', 
    'prType': 'M', 
    'prValue': 'LVA', 
    'prChannelDesc': '', 
    'prClass': '', 
    'prLine': ''
} 

As you can see, it isn't correctly populating any of the parameters except the ones I send in.

Copyfile for service program:

#!rpg

/02   *************************************************************************                     
/02   * GetProductHierarchy - will read up through the nf product                                   
/02   *   hierarchy to return the values and descriptions.                                          
/02   *   If a part a type of P is passed in for part will get the                                  
/02   *   hierarchy from PM.                                                                        
/02   *   All values below in the hierarchy will be blank.                                          
/02   *                                                                                             
/02   *   prType(incoming)   = product hierarchy type                                               
/02   *                                                                                             
/02   *   prValue(incoming)  = the channel, mpg, class or                                           
/02   *                                 line value.                                                 
/02   *                        H = Channel                                                          
/02   *                        M = MPG                                                              
/02   *                        C = Class                                                            
/02   *                        L = Line                                                             
/02   *                        P = Part                                                             
/02   *   prChannel(outgoing) = Product Channel                                                     
/02   *   prChannelDesc       = Channel Description                                                 
/02   *   prMPG               = Product MPG                                                         
/02   *   prMPGDesc           = MPG Description                                                     
/02   *   prClass             = Product Class                                                       
/02   *   prClassDesc         = Class Description                                                   
/02   *   prLine              = Product Line                                                        
/02   *   prLineDesc          = Line Description                                                    
/02   *                                                                                             
/02   *   ex. Incoming Values                                                                       
/02   *        prType = 'L'                                                                         
/02   *        prValue= 'UP'                                                                        
/02   *                                                                                             
/02   *   Outgoing Values                                                                           
/02   *   prChannel     = 'B'                                                                       
/02   *   prChannelDesc = 'Utility'                                                                 
/02   *   prMPG         = 'LVA'                                                                     
/02   *   prMPGDesc     = 'LOW VOLTAGE ALUMINUM'                                                    
/02   *   prClass       = '71'                                                                      
/02   *   prClassDesc = UNDERGROUND SERVICE                                                         
/02   *   prLine = UP                                                                               
/02   *   prLineDesc = US-MULTI-CONDUCTOR ABUSE RESISTANT                                           
/02   *                                                                                             
/02   *************************************************************************                     
/02  DGetProductHierarchy...                                                                        
/02  D                 Pr             1n   ExtProc('GetProductHierarchy')                           
/02  D  prFormat                     10a   Value                                                    
/02  D  prType                        1a   Value                                                    
/02  D  prValue                      15a   Value                                                    
/02  D  prChannel                     5a                                                            
/02  D  prChannelDesc                50a                                                            
/02  D  prMPG                         5a                                                            
/02  D  prMPGDesc                    50a                                                            
/02  D  prClass                       5a                                                            
/02  D  prClassDesc                  50a                                                            
/02  D  prLine                        5a                                                            
/02  D  prLineDesc                   50a                                                            
/02  D  prPart                       15a                                                            
/02  D  prPartDesc                   30a                                                            
/03                                                                                                 
/03   *************************************************************************

Source of relevant program:

#!rpg

/01   //*****************************************************
/01   //* Retrieve the Product Hierarchy                    *
/01   //*****************************************************
/01
/01  PGetProductHierarchy...
/01  P                 B                   Export
/01  DGetProductHierarchy...
/01  D                 Pi             1n
/01  D  p0Format                     10a   Value
/01  D  p0Type                        1a   Value
/01  D  p0Value                      15a   Value
/01  D  p0Channel                     5a
/01  D  p0ChannelDesc                50a
/01  D  p0MPG                         5a
/01  d  p0MPGDesc                    50a
/01  d  p0Class                       5a
/01  d  p0ClassDesc                  50a
/01  d  p0Line                        5a
/01  d  p0LineDesc                   50a
/01  d  p0Part                       15a
/01  d  p0PartDesc                   30a
/01
/01  d nfpds         e ds                  extname(nfp) Qualified
/01  d pmpds         e ds                  extname(pmp) Qualified
/01
/01  d format          s             10a   Inz
/01  d NfType          s              2a   Inz
/01  d NfValue         s              5a   Inz
/01  d Part            s             15a   Inz
/01  d NoteInformationV00...
/01  d                 ds                  LikeDs(ObjNoteFileDsV00)
/01  d ProductInformationDSV00...
/01  d                 ds                  LikeDs(ObjProductMasterDSV00)
/01  d ReturnFlag      s              1n   Inz(*on)
/01  d HierarchyFlag   s              1n   Inz(*off)
/01
/01   /Free
/01
/01       If  p0format <> *blanks
/01            and p0format = 'V00';
/01            Return ReturnFlag = *off;
/01       EndIf;
/01
/01      // If the part is passed in get the line level from
/01      // PMP and then go to the note file to get the hierarchy starting at
/01      // the line level
/01       If p0Type = 'P';   //Part
/01          Part = p0Value;
/01          clear pmpds;
/01          clear format;
/01          getProductMaster(format:Part:
/01                          %len(ProductInformationDSV00):
/01                          ProductInformationDSV00);
/01          eval-corr  pmpds = ProductInformationDSV00;
/01          If Part      = pmpds.pmpart;
/01            p0Part     = pmpds.pmpart;
/01            p0PartDesc = pmpds.pmdesc;
/01            p0Value    = pmpds.pmplin;
/01          Else;
/01            HierarchyFlag = *on;
/01            ReturnFlag = *off;
/01          EndIf;
/01       EndIf;
/01
/01      // Set the note file type
/01       Select;
/01         When p0Type = 'P';
/01           NfType = 'PL';
/01         When p0Type = 'L';
/01           NfType = 'PL';
/01         When p0Type = 'C';
/01           NfType = 'PR';
/01         When p0Type = 'M';
/01           NfType = 'MG';
/01         When p0Type = 'H';
/01           NfType = 'MR';
/01       EndSl;
/01       NfValue = p0Value;
/01
/01      // Loop through the note files to get the hierarchy
/01       Dow HierarchyFlag = *off;
/01          clear nfpds;
/01          clear format;
/01          getnotefile(format:NfType:NfValue:00:
/01                          %len(NoteInformationV00):
/01                          NoteInformationV00);
/01          eval-corr nfpds = NoteInformationV00;
/01
/01      // Check if the note type is found. If not turn off the result flag and leave the loop
/01          If NfType = *blanks
/01            or NfType <> nfpds.nftyp;
/01            ReturnFlag = *off;
/01            Leave;
/01          EndIf;
/01
/01      // Populate the return values and set the values for the next hierarchy level.
/01          If nfType = 'PL';
/01             p0Line = nfpds.nfnumb;
/01             p0LineDesc = %subst(nfpds.nfdesc:1:48);
/01             NfType = 'PR';
/01             NfValue = %subst(nfpds.nfdesc:49:2);
/01          ElseIf nfType = 'PR';
/01             p0Class = nfpds.nfnumb;
/01             p0ClassDesc = %subst(nfpds.nfdesc:1:45);
/01             NfType = 'MG';
/01             NfValue = %subst(nfpds.nfdesc:46:5);
/01          ElseIf nfType = 'MG';
/01             p0MPG = nfpds.nfnumb;
/01             p0MPGDesc = %subst(nfpds.nfdesc:1:39);
/01             NfType = 'MR';
/01             NfValue = %subst(nfpds.nfdesc:40:1);
/01          ElseIf nfType = 'MR';
/01             p0Channel = nfpds.nfnumb;
/01             p0ChannelDesc = %subst(nfpds.nfdesc:1:39);
/01             HierarchyFlag = *on;
/01          EndIf;
/01        EndDo;
/01
/01        Return ReturnFlag;
/01
/01   /End-Free
/01
/01  PGetProductHierarchy...
/01  P                 E     

Let me know if there is anything else you need. I realize this may fall outside the scope of the project, so if you cannot help, I understand.

Thanks in advance!

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


Also ... thank you for finding the documentation error. The iparm did not belong.

#!python

class iData (iBase)


    Data value child node for iPgm, iSrvPgm,
    or iDS data structures.

    Args:
      ikey  (str): XML <data ... var="ikey"> for parsing output.
      itype (obj): data type [see XMLSERVICE types, '3i0', ...].
      ival  (obj): data type value.
      iopt (dict): option - dictionay of options (below)
        {'dim':'n'}               : optional - XMLSERVICE dimension/occurs number.
        {'varying':'on|off|2|4'}  : optional - XMLSERVICE varying {'varying':'off'}.
        {'hex':'on|off'}          : optional - XMLSERVICE hex chracter data {'hex':'off'}.
        {'enddo':'label'}         : optional - XMLSERVICE enddo until label.
        {'setlen':'label'}        : optional - XMLSERVICE set calc length label.
        {'offset':'n'}            : optional - XMLSERVICE offset label.
        {'next':'label'}          : optional - XMLSERVICE next offset label (value).

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


Close to the weekend. So here is an example srvpgm call.

#!python

#     D ARRAYMAX        c                   const(999)
#     D dcRec_t         ds                  qualified based(Template)
#     D  dcMyName                     10A
#     D  dcMyJob                    4096A
#     D  dcMyRank                     10i 0
#     D  dcMyPay                      12p 2
#      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#      * zzarray: check return array aggregate 
#      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#     P zzarray         B                   export
#     D zzarray         PI                  likeds(dcRec_t) dim(ARRAYMAX)
#     D  myName                       10A
#     D  myMax                        10i 0
#     D  myCount                      10i 0
itool = iToolKit()
itool.add(iCmd('chglibl', 'CHGLIBL LIBL(XMLSERVICE)'))
itool.add(
 iSrvPgm('zzarray','ZZSRV','ZZARRAY')
 .addParm(iData('myName','10a','ranger'))
 .addParm(iData('myMax','10i0','8'))
 .addParm(iData('myCount','10i0','',{'enddo':'mycnt'}))
 .addRet(
  iDS('dcRec_t',{'dim':'999','dou':'mycnt'})
  .addData(iData('dcMyName','10a',''))
  .addData(iData('dcMyJob','4096a',''))
  .addData(iData('dcMyRank','10i0',''))
  .addData(iData('dcMyPay','12p2',''))
  )
 )

from python-itoolkit.

kadler avatar kadler commented on May 29, 2024

Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).


You will need to post your example for comment.

from python-itoolkit.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.