Reputation: 955
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
Upvotes: 0
Views: 296
Reputation: 955
Finally a real working solution.
With the encouragement and support of @SimonSobisch and other members of the gnucobol community, i was able to improve the configuration process to correctly employ libdb even in cross compiling cases.
You may try this for yourself by downloading the artifacts off my repository "final test" workflow at github for your own android architecture. I could only test with aarch64.
My hope, is that the termux packages maintainers will soon approve my patch to their main repository, by this pull request, which I encourage you to follow.
Upvotes: 0
Reputation: 955
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.
Upvotes: 0
Reputation: 955
While my newbie status in Cobol would primarly suggest it's my programming error, the problem seems to be specific to my environment.
I'm learning cobol on my phone, and gnucobol runs very well on termux. This is the first problem I've encountered, and have reported it on the packages' issues list.
The only difference seeming relevant between the termux environment and my other linux is the indexed file provider. On termux is vbisam, while on my linux it's bdb.
To further insulate the problem, I'd test a vbisam implementation under another environment.
Please join me and give your insights on the issue I opened on GitHub.
I extend a big thank to @SimonSobisch, that put me on the trail to solve this problem, and to everyone else making gnucobol thrive.
Upvotes: 0