First, transaction items are written to the input directory, called IDATA. The items are structured something like this:
That translates to: Code 1001 means Read a record. The source of the data is resource 12345. The ID is 123. The file name for this record is a unique ID generated off the current system timestamp.
Why a "resource ID" and not a filename? Because I want this code to work whether the server uses filename CONTACT or CUSTOMER or CUSTMAST… By passing a simple resource reference, the server is free to get the data in whatever way it knows how, even by calling to another system (if possible) or by generating the data in a program. Resource 12345 might be a request to get raw data from a file, while 12346 might request the data in mixed case format. The point here is that the client GUI doesn’t need to know how the data is produced – the server manages all of that.
What other codes can we use? Well for right now there’s only 1001 for reading, 1002 for writing, and 1003 for deleting – obviously there is plenty of room for asking the server to do a lot of things.
That request is written to IDATA and the DBMS … does absolutely nothing. The reason is that the DBMS has no way to know when I’m writing a multi-part set of data to be imported into many files, or if this is a simple one-item request. So the request is written but the server does nothing until it sees a single record called START. So after writing the request, I write a null file/record which triggers the MV BASIC code to read everything and start processing.
The BASIC code has a table to decode the request (1001) and the resource (12345 translates to the CONTACT file for right now). Given those cues it knows the last field is an ID to be used in a READ against the file. It reads the record, writes it to the outbound directory called ODATA, and GUI … does absolutely nothing. Again, the GUI doesn’t know what to expect. The BASIC code writes the data into ODATA with a random ID. It then writes a response record containing the filename where the data is contained, and the filename for this record is the timestamp ID that was provided by the client GUI. Finally, the BASIC code writes a single empty DONE record – and that’s what triggers the client code.
The mechanism is hardcoded to use the START/DONE triggers but as you can imagine, the unique IDs also facilitate enhancements to allow the client to spawn off many requests and to recognize each unique response as it becomes available. I’m not getting that sophisticated here but it not a tough stretch if it becomes a desired feature.
How do we keep the records from walking on one another? At the moment, when the BASIC code sees IDATA, it immediately clears ODATA in preparation for saving new responses. The assumption is that the client is not reading responses at the same time it’s dropping new requests. Of course that theory will need minor rework per the last paragraph if the client and server really are processing multiple requests simultaneously. After writing ODATA, just prior to writing the DONE record, the BASIC code clears IDATA – again because we know for now that the client is not making changes to that directory while it’s waiting for a response. So with this see-saw mechanism data is cleanly moved from input to output.
The data written to ODATA isn’t in the form of raw MV items. For right now (and here’s why it’s fragile) I’m using tilde’s to delimit fields, and then I’m parsing against these single character delimiters in the client. The client knows what it requested, so it knows exactly how to parse the return data. I can easily change the delimited from tilde to CHAR(1) or some other unprintable ASCII value – that would avoid the case where a user enters a tilde as data. I actually did this intentionally to show an obvious case of a fragile data structure. Given this sort of consideration it’s easier to see why many developers prefer XML, and why some data transfer protocols get messed up because some unexpected binary code made it into the pipe. I can easily fix this problem with minor changes to both the client and server code.