Comments (39)
Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).
long time fixed
from python-itoolkit.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).
(incorrect python syntax removed -- see last entry)
from python-itoolkit.
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.
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
- Build the XML manually to include the
by="val"
- 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.
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.
Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).
Well ... i have two answers ...
-
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.
-
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.
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.
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.
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.
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.
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.
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.
Original comment by Tony Cairns (Bitbucket: rangercairns, GitHub: rangercairns).
You will need to post your example for comment.
from python-itoolkit.
Related Issues (20)
- Drop Python 3.4 Support HOT 4
- _direct.py needs more test coverage
- Add type declarations HOT 17
- Transports need a way to indicate failure HOT 1
- Deprecate the trace functions for standard logging
- Run cl command to create a library in an IASP via DirectTransport on a French system failed HOT 1
- On Japanese or French systems run command via DatabaseTransport fails with ibm_db_dbi::Error HOT 3
- Provide a close() API to close database connections
- PyPI page is outdated HOT 5
- Is there a problem with the Japanese environment in iCmd5250 xml output? HOT 3
- What itoolkit version allows qtemp schema table access using iSqlQuery? HOT 6
- Improve README links on PyPI HOT 3
- RTVJOBA example works only with CCSID=37 HOT 3
- Errors using JayDeBeApi HOT 8
- DatabaseTransport should not close a connection HOT 14
- Stderr handling in SSH Transport can yield wrong results
- Running itool.call ends the program and does nothing HOT 7
- XML Special Character errors/handling HOT 1
- Fix license headers on source files HOT 2
- Error calling Receive DataQ API - QRCVDTAQ HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from python-itoolkit.