/* OpenCOBOL SQLite/3 interface * Author: Brian Tiffin * Date: 16-Sep-2008 * Rights: Copyright (c) 2008 OpenCOBOL project * Requires: libsqlite3, sqlite3-dev * Tectonics: cobc -c ocsqlite.c * cobc -x -lsqlite3 sqlcaller.cob ocsqlite.o */ #include #include #include /* Need to stash the COBOL callback procedure address and name/value lengths */ /* This routine sends an unused pointer, field count, field index, name, value */ static int (*ocsql_callback)(void*, int*, int*, char*, char*); static int ocsql_namelen; static int ocsql_datalen; /* wrap the COBOL callback */ static int cobolback(void *NotUsed, int argc, char **argv, char **azColName) { int i, recnum, ret; char name[ocsql_namelen]; char value[ocsql_datalen]; /* we are changing the nature of the callback for OpenCOBOL */ for (i = 0; i < argc; i++) { memset(name, ' ', ocsql_namelen); memset(value, ' ', ocsql_datalen); strncpy(name, azColName[i], ocsql_namelen); /* The strncpy keeps the null if there is room, * and COBOL can use this? or should it be spaced? */ //if (name[ocsql_namelen-1] == '\0') { // name[ocsql_namelen-1] = ' '; //} strncpy(value, argv[i], ocsql_datalen); //if (value[ocsql_datalen-1] == '\0') { // value[ocsql_datalen-1] = ' '; //} ret = ocsql_callback(NotUsed, &argc, &i, name, value); } return ret; } /* Open a database */ int sqlopen(sqlite3 **db, char *dbname, char *errstr, int errlen) { int rc; rc = sqlite3_open(dbname, db); if (rc) { memset(errstr, ' ', errlen); strncpy(errstr, sqlite3_errmsg(*db), errlen); if (errlen > 0 && errstr[errlen-1] == '\0') { errstr[errlen-1] = ' '; } sqlite3_close(*db); } return rc; } // int sqlexec(sqlite3 *db, int (*ocback)(void*, int, char**, char**), char *query, int qlen, char *errstr, int errlen) { /* the wrapped sqlite exec function */ int sqlexec(sqlite3 *db, int (*ocback)(void*, int*, int*, char*, char*), char *query, int qlen, char *errstr, int errlen, int namelen, int datalen) { int rc; char *errmsg = 0; /* Stash away the COBOL callback and field data and field name lengths */ ocsql_namelen = namelen; ocsql_datalen = datalen; ocsql_callback = ocback; /* Evaluate the sql query, wrapping the callback */ rc = sqlite3_exec(db, query, cobolback, 0, &errmsg); if (rc != SQLITE_OK) { if (errmsg != NULL) { memset(errstr, ' ', errlen); strncpy(errstr, errmsg, errlen); if (errlen > 0 && errstr[errlen-1] == '\0') { errstr[errlen-1] = ' '; } sqlite3_free(errmsg); } } return rc; } /* Close a db connection */ int sqlclose(sqlite3 *db) { int rc; rc = sqlite3_close(db); return rc; }