Search code examples
cobolgnucobol

gnucobol failing to open/create an indexed file


Following a course in COBOL, I'm trying to create an indexed file.

Many times the file reading chapter precedes the writing one, so I had no file to read, and an indexed file is not just a file.

Anyway, my following program is failing to fill data in the students file, although the students.dat and students.idx files are being created. .dat has zero size and .idx 12288 bytes. This might say an underlaying bdb or vbisam has been invoked.

Could you try to help me out?

IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO.

ENVIRONMENT DIVISION.
   INPUT-OUTPUT SECTION.
      FILE-CONTROL.
      SELECT optional STUDENT-DB ASSIGN TO 'students'
         ORGANIZATION IS INDEXED
         ACCESS IS RANDOM
         RECORD KEY IS DB-STUDENT-ID
         FILE STATUS IS FS.

DATA DIVISION.
   FILE SECTION.

   FD STUDENT-DB.
   01 DB-STUDENT.
      05 DB-STUDENT-ID PIC 9(5).
      05 DB-NAME PIC A(25).
      05 DB-CLASS PIC X(3).

   WORKING-STORAGE SECTION.
   01 FS PIC X(2).

PROCEDURE DIVISION.
   OPEN i-o STUDENT-DB.
   DISPLAY "FS open : "FS END-DISPLAY. *>30
   move 1000 TO DB-STUDENT-ID.
   move 'Tim' TO DB-NAME.
   move '10' TO DB-CLASS.
   DISPLAY 'DB-STUDENT-ID : 'DB-STUDENT-ID END-DISPLAY.
   DISPLAY 'DB-NAME : 'DB-NAME END-DISPLAY.
   DISPLAY 'DB-CLASS : 'DB-CLASS END-DISPLAY.
   DISPLAY 'DB-STUDENT : 'DB-STUDENT END-DISPLAY.
   WRITE DB-STUDENT END-WRITE.
   DISPLAY "FS write : "FS END-DISPLAY. *>48
   CLOSE STUDENT-DB.
   DISPLAY "FS close : "FS END-DISPLAY. *>42
STOP RUN.

This is my output:

FS open : 30
DB-STUDENT-ID : 01000
DB-NAME : Tim
DB-CLASS : 10
DB-STUDENT : 01000Tim                      10
FS write : 48
FS close : 42

and my compilation command:

cobc -d -free -Wall -Wextra -Wadditional -x index-create.cbl
$ cobcrun --info #gives on termux:
GnuCOBOL information
COB_MODULE_EXT           : so
dynamic loading          : system                          64bit-mode               : yes
BINARY-C-LONG            : 8 bytes
endianness               : little-endian
native EBCDIC            : no                              variable file format     : 0
sequential file handler  : built-in
indexed file handler     : VBISAM
mathematical library     : GMP, version 6.3.0
XML library              : libxml2, version 2.12.7
JSON library             : json-c, version 0.17.0
extended screen I/O      : ncursesw, version 6.4.20231001 (CHTYPE=32, WIDE=1)
mouse support            : unknown

a big thank in advance, alex


Solution

  • To further inquire this issue, i wrote a small program in c, that accesses and eventually creates a bdb file. The program runs correctly.

    Didn't use any special release of libdb, just the prepackaged one, version 18.1.4.

    #include <db.h>
    #include <string.h>
    #include <stdio.h>
    
    DB *bdb_create() {
        DB *db;
    
        /* setup the database memory structure */
        int ret = db_create(&db, NULL, 0);
        printf("create status %d\n", ret);
        return db;
    }
    
    int bdb_open(DB *db, const char *filename) {
        int ret = db->open(
            db, 
            NULL, 
            filename,
            NULL,
            DB_BTREE,
            DB_CREATE,
            0
        );
        printf("open status %d\n", ret);
        return ret;
    }
    
    int bdb_put(DB *db, const char *name, int id) {
        DBT key, value;
    
        memset(&key, 0, sizeof(DBT));
        memset(&value, 0, sizeof(DBT));
        
        /* setup the key */
        key.data = &id;
        key.size = sizeof(int);
        
        /* setup the value */
        value.data = (void *)name;
        value.size = strlen(name) + 1;
        
        /* write it into the database */
        int ret = db->put(
            db, 
            NULL, 
            &key, 
            &value, 
            DB_NOOVERWRITE
        );
        printf("put status %d\n", ret);
        return ret;
    }
    
    int bdb_get(DB *db, char *name, size_t max_name, int *id) {
        DBT key, value;
    
        memset(&key, 0, sizeof(DBT));
        memset(&value, 0, sizeof(DBT));
    
        /* setup the key to read */
        key.data = id;
        key.size = sizeof(int);
        
        /* setup the value to fill */
        value.data = name;
        value.ulen = max_name;
        value.flags = DB_DBT_USERMEM;
        
        int ret = db->get(
            db, 
            NULL, 
            &key, 
            &value, 
            0
        );
        printf("get status %d\n", ret);
        return ret;
    }
    
    void bdb_close(DB *db) {
        if (db != NULL) {
            int ret = db->close(db, 0);
            printf("close status %d\n", ret);
            db = NULL;
        }
    }
    
    int main(int argc, char *argv[]) {
        DB *db = bdb_create();
        bdb_open(db, "test");
        int id = 123;
        bdb_put(db, "alex", id);
        char gotname[256];
        bdb_get(db, gotname, sizeof(gotname), &id);
        printf("the name of id %d is %s\n", id, gotname);
        bdb_close(db);
    
        return 0;
    }
    

    This example code is from a tutorial i found here

    To build the program on termux, I ran clang -ldb dbexample.c .

    I could build and corectly run the same program on Debian linux with gcc dbexample.c /usr/lib/aarch64-linux-gnu/libdb-5.3.a . I can't say why gcc isn't finding libdb.so.

    Under the same Debian machine, gnucobol can corectly open and optionaly create db indexed files.

    Will also post to sourceforge.