Sono un programmatore COBOL e il mio ultimo progetto è quello di connettere un'applicazione COBOL a un database SQLite3.Come scrivere callback SQLite in COBOL
Ho seguito this guide e la loro soluzione è esattamente ciò di cui avrei bisogno nella mia applicazione COBOL. Sono riuscito a creare, connettere, inserire dati e chiudere il database, ma il problema sorge quando provo a selezionare i dati dal database.
Nel tutorial, utilizzano una richiamata con doppi puntatori.
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;
}
La mia soluzione in COBOL è la seguente
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.
Il callback funziona perché si chiama il numero di righe che viene restituito dal database, e l'argc intero contiene il numero di colonne che le la tabella contiene.
Le domande sono:
puntatoridoppie in COBOL, come sono rappresentati? Nella mia soluzione dichiaro un puntatore e richiamo il callback con "per riferimento" sul puntatore. Non so se questo è il modo corretto per rappresentare i doppi puntatori in COBOL?
Come visualizzare il contenuto di azColName e argv e non solo l'indirizzo di memoria a cui punta il puntatore?
Ho cercato ora di utilizzare SET ADDRESS OF, ma non riesco ancora a farlo funzionare. Deve essere qualcosa che mi è sfuggito. La mia soluzione al momento appare come:
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.
Il risultato che ottengo è che l'istruzione if è sempre false, quindi viene visualizzata la stringa "vuoto". Ma ancora argc è impostato sul numero di colonne nella tabella.
La soluzione di lavoro:
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.
Quale COBOL stai utilizzando? Si compila senza una SEZIONE COLLEGAMENTO? Dai un'occhiata a SET ADDRESS OF x TO your-pointer, dove x è definito nella LINKAGE SECTION ed è la dimensione e il tipo che vuoi. Ciò consentirà quindi l'accesso ai dati indicati dal puntatore. –
Marcus sta utilizzando un compilatore MicroExcenter ServerExpress. – Anders