Issue using yajl_saveBuf
Issue using yajl_saveBuf
Good afternoon!
I'm new to using the YAJL functions.
I'm getting a compile error after I add yajl_saveBuf function to my program. Program compiles successfully until I add this one line of code.
yajl_saveBuf('/temp/example.json': errMsg);
What am I missing here? Do I need to add another library?
Thanks,
Trent
I'm new to using the YAJL functions.
I'm getting a compile error after I add yajl_saveBuf function to my program. Program compiles successfully until I add this one line of code.
yajl_saveBuf('/temp/example.json': errMsg);
What am I missing here? Do I need to add another library?
Thanks,
Trent
-
- Site Admin
- Posts: 872
- Joined: Sun Jul 04, 2021 5:12 am
Re: Issue using yajl_saveBuf
What error do you receive?
Re: Issue using yajl_saveBuf
I figured it out Scott! I didn't realize that the parms had to be defined the exact same way.
I'm now able to successfully write Json created with YAJL functions to IFS directory.
Thanks,
Trent
I'm now able to successfully write Json created with YAJL functions to IFS directory.
Thanks,
Trent
Re: Issue using yajl_saveBuf
Scott,
I'm having trouble getting the yajl_copyBuf function to work. I've pasted some of my code below.
Do you see anything wrong with what I'm doing? Just to verify that the buffer was getting populated I tried using the yajl_copyBufStr and it works correctly.
dcl-proc Get_Buffer_Data;
dcl-s JSONDataLength int(10);
dcl-c ToCCSID const(37);
dcl-s jsonData varchar(32000);
yajl_copyBuf( ToCCSID: %addr(jsonData: *Data):
%size(jsonData): JSONDataLength);
jsonData = yajl_copyBufStr();
return;
end-proc Get_Buffer_Data;
I'm having trouble getting the yajl_copyBuf function to work. I've pasted some of my code below.
Do you see anything wrong with what I'm doing? Just to verify that the buffer was getting populated I tried using the yajl_copyBufStr and it works correctly.
dcl-proc Get_Buffer_Data;
dcl-s JSONDataLength int(10);
dcl-c ToCCSID const(37);
dcl-s jsonData varchar(32000);
yajl_copyBuf( ToCCSID: %addr(jsonData: *Data):
%size(jsonData): JSONDataLength);
jsonData = yajl_copyBufStr();
return;
end-proc Get_Buffer_Data;
-
- Site Admin
- Posts: 872
- Joined: Sun Jul 04, 2021 5:12 am
Re: Issue using yajl_saveBuf
Is there a reason you need to use yajl_copyBuf() instead of yajl_copyBufStr()?
The obvious problem with your yajl_copyBuf code (or at least the part you've provided) is that you aren't bothering to set the length of the buffer, and you're providing an incorrect length to the routine.
Pointer and raw memory techniques do require a little bit more knowledge and understanding of how the computer works. That's why I provided yajl_copyBufStr(), so you don't need to worry about that stuff.
The obvious problem with your yajl_copyBuf code (or at least the part you've provided) is that you aren't bothering to set the length of the buffer, and you're providing an incorrect length to the routine.
Pointer and raw memory techniques do require a little bit more knowledge and understanding of how the computer works. That's why I provided yajl_copyBufStr(), so you don't need to worry about that stuff.
-
- Site Admin
- Posts: 872
- Joined: Sun Jul 04, 2021 5:12 am
Re: Issue using yajl_saveBuf
Code: Select all
%len(jsonData) = %len(jsonData:*max); <-- set the length of the varchar to its maximum size
yajl_copyBuf( ToCCSID: %addr(jsonData: *Data): %len(jsonData): JSONDataLength); <-- use the max length (not %size)
%len(jsonData) = JSONDataLength; <-- set the length of the VARCHAR to the length in the buffer
Code: Select all
jsonData = yajl_copyBufStr();
Re: Issue using yajl_saveBuf
Scott,
My goal was to hopefully be able to use the data from the buffer in SQL/HTTP functions.
SQL Webservices has a 32k variable size limit as far as I can tell.
I would like to send more than 32k when using the HTTP post function.
EXEC SQL
SELECT RESPONSE_MESSAGE, RESPONSE_HTTP_HEADER
INTO :rspData, :rspHdr
FROM TABLE(QSYS2.HTTP_POST_VERBOSE(
CAST(trim(:myUrl) AS VARCHAR(500)),
CAST(trim(:jsonData) AS VARCHAR(32000)),
CAST(trim(:myHdr) AS VARCHAR(5000))));
Hopefully that makes sense.
My goal was to hopefully be able to use the data from the buffer in SQL/HTTP functions.
SQL Webservices has a 32k variable size limit as far as I can tell.
I would like to send more than 32k when using the HTTP post function.
EXEC SQL
SELECT RESPONSE_MESSAGE, RESPONSE_HTTP_HEADER
INTO :rspData, :rspHdr
FROM TABLE(QSYS2.HTTP_POST_VERBOSE(
CAST(trim(:myUrl) AS VARCHAR(500)),
CAST(trim(:jsonData) AS VARCHAR(32000)),
CAST(trim(:myHdr) AS VARCHAR(5000))));
Hopefully that makes sense.
-
- Site Admin
- Posts: 872
- Joined: Sun Jul 04, 2021 5:12 am
Re: Issue using yajl_saveBuf
Trent,
yajl_copyBufStr() allows up to 2 million characters. (Granted, yajl_copyBuf can allow much more -- but... that's a far cry from 32k!!)
HTTP_POST_VERBOSE allows for up to 2 gigabytes -- which is almost much more than 32k -- BUT, you appear to be declaring your field as VARCHAR. VARCHAR in RPG (and therefore with YAJL or HTTPAPI) can be up to 16mb in size. But SQL only allows VARCHAR to be 32k, because SQL expects the VARCHAR to be a column in a row (aka field in a record) and therefore needs to be relatively small. SQL is designed for databases, after all.
To allow larger values, SQL has "large object support", aka LOBs. In this case, it'd be a character LOB (aka CLOB) that you need to use for larger values. So you'll have to decare and populate your RPG variable as a CLOB (or stop using SQL for HTTP -- and use something else like HTTPAPI)
This has nothing whatsoever to do with YAJL -- it's about how SQL works.
yajl_copyBufStr() allows up to 2 million characters. (Granted, yajl_copyBuf can allow much more -- but... that's a far cry from 32k!!)
HTTP_POST_VERBOSE allows for up to 2 gigabytes -- which is almost much more than 32k -- BUT, you appear to be declaring your field as VARCHAR. VARCHAR in RPG (and therefore with YAJL or HTTPAPI) can be up to 16mb in size. But SQL only allows VARCHAR to be 32k, because SQL expects the VARCHAR to be a column in a row (aka field in a record) and therefore needs to be relatively small. SQL is designed for databases, after all.
To allow larger values, SQL has "large object support", aka LOBs. In this case, it'd be a character LOB (aka CLOB) that you need to use for larger values. So you'll have to decare and populate your RPG variable as a CLOB (or stop using SQL for HTTP -- and use something else like HTTPAPI)
This has nothing whatsoever to do with YAJL -- it's about how SQL works.
Re: Issue using yajl_saveBuf
Scott,
I really appreciate your help! I've got one more question for ya!
I'm moving the data from the copyBufStr function into a clob variable.
Once I try to use the clob variable inside the SQL statement I get the error below.
Length in varying-length, LOB, or XML host variable not valid.
Cause . . . . . : Host variable JSONDATA was specified. The value in the
length portion of the variable length, LOB, or XML host variable is either
negative or greater than the declared length. If the host variable is
graphic the length should be the number of DBCS characters. The host
variable number is 2. The specified length is -1065379967. The variable is
declared to have length 100000.
Recovery . . . : Change the length portion of the varying-length, LOB, or
XML host variable to a valid positive number or zero. Try the request again.
dcl-s jsonData SQLTYPE(CLOB:100000) inz;
jsonData = yajl_copyBufStr();
EXEC SQL
SELECT RESPONSE_MESSAGE, RESPONSE_HTTP_HEADER
INTO :rspData, :rspHdr
FROM TABLE(QSYS2.HTTP_POST_VERBOSE(
CAST(trim(:myUrl) AS VARCHAR(500)),
CAST(trim(:jsonData) AS CLOB(100000)),
CAST(trim(:myHdr) AS VARCHAR(2000))));
I really appreciate your help! I've got one more question for ya!
I'm moving the data from the copyBufStr function into a clob variable.
Once I try to use the clob variable inside the SQL statement I get the error below.
Length in varying-length, LOB, or XML host variable not valid.
Cause . . . . . : Host variable JSONDATA was specified. The value in the
length portion of the variable length, LOB, or XML host variable is either
negative or greater than the declared length. If the host variable is
graphic the length should be the number of DBCS characters. The host
variable number is 2. The specified length is -1065379967. The variable is
declared to have length 100000.
Recovery . . . : Change the length portion of the varying-length, LOB, or
XML host variable to a valid positive number or zero. Try the request again.
dcl-s jsonData SQLTYPE(CLOB:100000) inz;
jsonData = yajl_copyBufStr();
EXEC SQL
SELECT RESPONSE_MESSAGE, RESPONSE_HTTP_HEADER
INTO :rspData, :rspHdr
FROM TABLE(QSYS2.HTTP_POST_VERBOSE(
CAST(trim(:myUrl) AS VARCHAR(500)),
CAST(trim(:jsonData) AS CLOB(100000)),
CAST(trim(:myHdr) AS VARCHAR(2000))));
-
- Site Admin
- Posts: 872
- Joined: Sun Jul 04, 2021 5:12 am
Re: Issue using yajl_saveBuf
When you use SQLTYPE(CLOB:100000) (as you did), the SQL precompiler will generate an RPG data structure under the covers. So if you look at the code it generated (for example, in the compile listing) you'll see something like this:
So you need to set two fields to populate the CLOB, not just one...
That's the way the SQL precompiler works (which, imho, is kinda clumsy -- but, hard to change it at this point, too many people are using it.)
Code: Select all
DCL-DS JSONDATA;
JSONDATA_LEN UNS(10);
JSONDATA_DATA CHAR(100000);
END-DS;
Code: Select all
jsonData_data = yajl_copyBufStr();
jsonData_Len %len(%trimr(jsonData_data));