program PBook;
type
EntryRec = record
Name: string[32];
Phone: string[30];
end;
var
Entries: File of EntryRec;
Entry: EntryRec;
C: Char;
I: Longint;
begin
Assign(Entries, 'entries.dat');Reset(Entries);
repeat
Write('Phone book, what to do? (Enter, List, Modify, Quit) ');
Readln(C); C:=UpCase(C);
if C='E' then begin
Write('Name: '); Readln(Entry.Name);
Write('Phone: '); Readln(Entry.Phone);
Seek(Entries, FileSize(Entries));
Write(Entries, Entry);
end else if C='L' then begin
Seek(Entries, 0);
while not Eof(Entries) do begin
Read(Entries, Entry);
Writeln('Name:', Entry.Name:32, ' Phone:', Entry.Phone:30);
end;
end else if C='M' then begin
Write('Entry number (0..', FileSize(Entries) - 1,'): ');Readln(I);
Seek(Entries, I);
Read(Entries, Entry);
Write('Name (', Entry.Name, '): ');Readln(Entry.Name);
Write('Phone (', Entry.Phone, '): ');Readln(Entry.Phone);
Seek(Entries, i);
Write(Entries, Entry);
end;
until C='Q';
Close(Entries);
end.
Many BASIC dialects, like GW-Basic, also had support for record-based files. Though since they often didn't have explicit type support these records were defined in terms of how many fields and characters per field would fit in a record, but still you worked with what was essentially a flat-file database.And of course there were the more high level "4GL" languages that combined a full database and a (mostly) general purpose programming language, like dBase/FoxPro/etc. These also had features like a visual form editor that allowed building data entry and manipulation applications quickly.
COBOL has built-in support for accessing flat file databases with either sequential or indexed organisation. On many mainframe and minicomputer operating systems, the filesystem provides native support for record-oriented files (with fixed or variable width records) and indexed-key files, and COBOL directly integrates with that.
COBOL has syntax for defining nested record structures which was often used to define the data schema for these files. You could store the definitions in a "copybook" (conceptually equivalent to an include file in C/C++) and reuse it in many programs which would manipulate the same files.
COBOL itself doesn't directly support "querying", except for the strategies of (1) manually iterating through every record in a sequential file to find matching records or (2) looking up a key-indexed file by its key field.
There are commonly implemented extensions to COBOL to access relational databases (SQL), hierarchical databases (e.g. IMS), etc. However, those are not part of the core COBOL language, and comparable facilities are defined for many other languages, so COBOL isn't really unique on that point.
It doesn't seem to me that having built-in syntax for this is necessarily a big advantage, since Python can easily and naturally work with such databases using the built-in dbm module in the standard library (and has no need for defining the schema up front): https://docs.python.org/3/library/dbm.html
If you do need to define the database schema in code, there are many third-party libraries that allow you to do this cleanly using classes and fields, e.g. Django. Even Java can do this with Hibernate.
Python doesn't support accessing mainframe key-indexed files. There is a port of Python to z/OS [1], but the dbm module can't read/write VSAM KSDS files, and I don't believe there exists any other Python module that can either. (Of course, someone could write a Python C extension using the VSAM C interface, or create a module which calls it using ctypes–z/OS adds some functions to stdio like flocate,fupdate,fdelrec for VSAM access–but I don't think anyone has done that so far.) Now of course, if you are porting your app to another platform, this will not be an issue, but if your data is staying on the mainframe, Python doesn't know how to handle it, COBOL does.
> If you do need to define the database schema in code, there are many third-party libraries that allow you to do this cleanly using classes and fields, e.g. Django.
Mainframe systems tend to use file formats based on plain text records where fields are assigned to fixed ranges of columns. Is there a Python module to do that? Especially in a declarative way, which is what COBOL provides.
[1] https://www.rocketsoftware.com/product-categories/mainframe/...
My question was about the advantages of Cobol's built-in syntax for database access and it seems like, as you said, you could write a Python module for the mainframe database format if desired, and there would then be no particular advantage to Cobol's special syntax.
Edit: The J2ME environments used on phones 15 years ago also provided a database (Record Management System) which would be difficult to access from a language other than Java, but that's unrelated to the question of whether the "programming language itself has no clue about database layout".
In terms of data structures, imagine you are working in an environment in which you have hundreds of pre-existing data files defined by COBOL copybooks, which look like the example on this page: https://www.ibm.com/support/knowledgecenter/en/SSMQ4D_3.0.0/...
Now, in COBOL, you just include that in your program and then you can parse the file. In Java, well Java has no built-in support for that, but IBM has a product called IBM Record Generator for Java which uses COBOL copybooks to generate Java classes. I'm sure someone could write an equivalent tool for Python. But as far as I am aware, no one has, and it would be a non-trivial amount of work to do.
> but that's unrelated to the question of whether the "programming language itself has no clue about database layout".
Well, that wasn't my statement, that was Animats'. Possibly what Animats was trying to say, is that in a classic COBOL environment, the language you use to define your database schema is built-in to your programming language, and uses the same syntax as you use to define in-memory data structures. That usually isn't true in other programming languages, including Python and Java, in many of their common usage patterns. In Java for example, you could store all your data using serialization, and then it would be much closer to how COBOL does it, but you normally don't do that. Or you use some kind of ORM framework like Hibernate, but then you end up with all these annotations which don't mean anything for in-memory data – or, in older versions of Hibernate, an XML file – which is further away from the classic COBOL model that describing in-memory data and on-disk/tape data is done identically.
However, not all COBOL code is "classic COBOL code" in that sense. Rather than storing data in files, many COBOL programs use a relational database, most commonly via the SQL precompiler (EXEC SQL). In that case, COBOL is basically no different than any of the other languages which support embedded SQL – the SQL standard defines embedded SQL support for Ada, C, COBOL, FORTRAN, MUMPS, Pascal, and PL/I (I know in the past Oracle RDBMS supported every one of those languages except for MUMPS, although in newer versions many of the precompilers have been discontinued due to lack of use.) Embedded SQL also exists for Java (SQLJ), although I've never seen anyone use that technology, almost everybody uses JDBC instead. I don't believe Embedded SQL is available for Python, but again, there is no reason why someone couldn't implement that if they wanted.