How to write SQLite callback in COBOL

I am a COBOL programmer, and my last project is to connect the COBOL application to the SQLite3 database.

I followed this guide and their solution is exactly what I need in my COBOL application. I managed to create, connect, insert data and close the database, but the problem occurs when I try to select data from the database.

In the tutorial, they use double pointer callbacks.

static int callback(void *NotUsed, int argc, char **argv, char **azColName){ int i; for(i=0; i<argc; i++){ printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); } printf("\n"); return 0; } 

My solution at COBOL is as follows

  WORKING-STORAGE SECTION. *----------------------------------------------------------------* 01 sqlite3-db pointer. 01 err_msg pointer. 01 sqlite pointer. 01 res pointer. 01 notused pointer. 01 argc pic 99 comp-5. 01 argv pointer. 01 azColName pointer. 01 Writefunction-Ptr procedure-pointer. procedure division. set Writefunction-Ptr to entry "sqlite-callback". *>Random code. call "sqlite3_exec" using by value sqlite3-db by reference sqlQuery by value Writefunction-Ptr by value 0 by reference err_msg returning rc end-call *>Random code. stop run. entry "sqlite-callback" using by value notused by value argc by reference argv by reference azColName. display argc goback. Entry-Termination. 

The callback works because it is called the number of rows returned from the database, and the integer argc contains the number of columns that the table contains.

Questions:

Double pointers in COBOL, how are they represented? In my solution, I declare a pointer and call the callback using the "by reference" on the pointer. Not sure if this is the right way to represent double pointers in COBOL?

How to display the contents of azColName and argv, and not just the memory address pointed to by the pointer?

Now I tried to use SET ADDRESS OF, but I still do not work. Something I must have missed. My solution at the moment is as follows:

 WORKING-STORAGE SECTION. 01 argv pointer. Linkage Section. 01 link-area pic x. procedure division using link-area. *> RANDOM CODE set address of link-area to argv call "sqlite3_exec" using by value sqlite3-db by reference z"SELECT * FROM Cars" by value Writefunction-Ptr by value 0 by reference err_msg returning rc end-call *> RANDOM CODE entry "sqlite-callback" using by value notused by value argc by reference argv by reference azColName. display argc. if address of link-area not = null display "Contents of new argv: " link-area else display "empty" end-if goback. Entry-Termination. 

The result is that the if statement is always false, so the string "empty" is displayed. But still, argc is set to the number of columns in the table.

Working solution:

  WORKING-STORAGE SECTION. 01 argv. 03 firstColumn pointer. 03 secondColumn pointer. 03 thirdColumn pointer. 01 azColName pointer. 01 argc pic 99 comp-5. 01 notused pointer. 01 Writefunction-Ptr procedure-pointer. *----------------------------------------------------------------- Linkage Section. 01 Cars_Id pic 9(2). 01 Cars_Name pic X(20). 01 Cars_Price pic 9(10). /----------------------------------------------------------------- procedure division. //code set Writefunction-Ptr to entry "sqlite-callback". initialize sqlQuery move z"SELECT * FROM Cars;" to sqlQuery call "sqlite3_exec" using by value sqlite3-db by reference sqlQuery by value Writefunction-Ptr by value 0 by reference err_msg returning rc end-call //code stop run. entry "sqlite-callback" using by value notused by value argc by reference argv by reference azColName. set address of Cars_Id to firstColumn set address of Cars_Name to secondColumn set address of Cars_Price to thirdColumn display Cars_Id "|" Cars_Name "|" Cars_Price goback. Entry-Termination. 
+6
source share
1 answer

We really need to know the compiler you are using.

Your SET statement is in the wrong place. argv only has an address when ENTRY is ENTRY . Before the record is called, it will be binary zero or some unpredictable garbage.

If you move SET after logging in, you must use the LINK-AREA value. argv will still only be an address, but LINK-AREA (give it a better name, please) will point to that address, so define it as argv, and then LINK-AREA can be used to get the actual contents of argv.


When using BY REFERENCE compiler generates code to pass a pointer with the address of the data element.

In PROCEDURE DIVISION USING or ENTRY USING element must also be BY REFERENCE, and the compiler generates code to map the LINKAGE SECTION definition to the passed address.

This is similar if you use BY CONTENT , but the compiler takes a copy of the data in your program and passes a pointer that references it. ABOUT USING A PROCEDURE OR ENTRANCE DEPARTMENT, which is still designated as REFERENCE.

With BY VALUE compiler "conveys" the actual value, although there are limitations specified in the standard or additions to the standard with your actual compiler. USING A PROCEDURE DEPARTMENT or RECORD should also indicate VALUE.

In all USES, HELP / CONTENT / VALUE are distributed, you do not need to specify BY at all, if all are the same, and you want BY REFERENCE, this is the default value.

If you โ€œpass inโ€ POINTER ( USAGE POINTER ), you can access the data specified using SET ADDRESS OF . The SET ADDRESS OF attribute must be in the LINKAGE SECTION .

You can also use an implicit pointer with SET ADDRESS OF. SET ADDRESS OF TO ADDRESS of b will change the address displayed in the LINKAGE SECTION section to address b, an element that is defined somewhere in your DATA DIVISION program (any SECTION other than FILE SECTION ).

If you want to see the data pointed to by POINTER, define an element that has the correct size and type, and use SET ADDRESS OF item to pointer name.

POINTER can, of course, point to a simple data item or group data item (structure).

All elements in the LINKAGE SECTION must have an address before links are specified. Those who use USING get addressing by the compiler (and the compiler assumes that the correct number of addresses / elements is passed). All other LINKAGE SECTION elements must have the addressing set by SET ADDRESS OF or by passing ADDRESS OF in USE of a CALL and having the CALLed program, set the address.

+3
source

All Articles