I'm a COBOL programmer , and my latest project is to connect a COBOL application to a SQLite3 database.
I have been following this guide, and their solution is exactly what I would need in my COBOL application. I have successfully managed to create, connect, insert data and close the database, but the problem arises when I try to select data from the database.
In the tutorial, they use a callback with double pointers.
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 in COBOL is the following
   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 that is returned from the database, and the integer argc contains the number of columns that the table contains.
The questions is:
Double pointers in COBOL, how are they represented? In my solution I declare a pointer and call the callback with "by reference" on the pointer. Don't know if this is the correct way to represent double pointers in COBOL?
How do I display the content of the azColName and argv, and not just the memory address which the pointer points to?
I hove now tried to use SET ADDRESS OF, but I still don´t get it to work. Must be something i´ve missed. My solution at the moment looks like:
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 I get is that the if statement is always false, so the string "empty" is displayed. But still argc is set to the number of colums in the table.
The 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.
 
    