home *** CD-ROM | disk | FTP | other *** search
- D I S C L A I M E R
-
-
- The code included is provided AS IS, with NO WARRANTY WHATEVER. If you chose
- to place it into your programs YOU are responsible for verifying that the
- overall program, including code furnished by HCWP, works. I will bear no
- liability OF ANY KIND for this code. And I will MOST CERTAINLY NOT guarantee
- it to work in YOUR program! All I can say is: It works here, in mine.
-
- DATAMAGE
-
- The draw_border function included with your sample places the DATAMAGE banner
- atop the screen. DATAMAGE is a registered trademark of Monte Ward and HCWP.
- You may NOT use it in your programs!
-
- THE CORE LIBRARY
-
- The module of code called HCWP_LIB.C is the core library, and has it's own
- docs in the file: HCWP_LIB.TXT.
-
- THE ISAM LIBRARY
-
- The module of code called MAGEISAM.C (and MAGEISAM.H) are the C language
- interface to DATAMAGE files. So far. This module was compiled with the QUICK
- C compiler (2.5) and, save a few of those dern long/short mis-matches, compiled
- perfectly. If you try to use another compiler, GOOD LUCK. MIGHT work, but
- you'll find dieeetomsbin and dmsbintoieee functions, which turn BASIC formatted
- double-floats into ieee formatted double-floats don't exist in many compilers,
- so be prepared to do it yourself.
-
- The module called MAGEDEMO.C uses SOME of the functions to create a simple
- program. It's purpose is to provide a practical demonstration of the use of
- the ISAM, and to provide a platform for your programs. It is NOT a slick,
- finished product. Merely a template.
-
- WHAT IS AN I.S.A.M. ?
-
- What we have, here, folks, is the GUTS of a database. ISAM stands for Indexed
- Sequential Access Method/Manager. In this module is the code to read/write
- records, find records, load DATAMAGE files - the basics.
-
- The DATAMAGE ISAM was designed for maximum speed, low disk/memory overhead, to
- make optimum use of MS-DOS and, most importantly, to be easy to program with.
- This is FAR easier/simpler than dBase methodology, for instance.
-
- DATAMAGE ISAM PARTICULARS
-
- The files are flat and assessable to the BASIC interpreter. So, you CAN write
- hybrid programs with it, if you must. But, PLEASE do yourself a favor and get
- QUICK BASIC if BASIC is your thing. See POWRMAIL.BAS.
-
- For those of us who prefer C, the format of the files on disk makes little
- difference. Whatever it is, we can handle it. But simplicity of
- design/operation and the aforementioned speed and LOW OVERHEAD are still
- valuable. And, of course, the accessibility of your files to the DATAMAGE
- system adds many features to your programs. The ISAM is NOT designed to be
- state-of-the-art, just to WORK (fast!) and to be used by ordinary human beings.
-
- DEFINITION FILES
-
- One BIG difference between DATAMAGE files and ordinary files produced by BASIC
- is that they have definition files. In a "dedicated" program definition files
- aren't necessary - we know the details of the file and hard-code them into our
- program. This necessary with some of the big-name ISAMs, like B-TRIEVE.
-
- Other files, like dBase, have the file definition "built in" to the main
- datafile. This makes it MURDER to process the file and almost completely dis-
- allows BASIC from processing the files. But, it DOES make it possible to
- transport the file more easily. To transport a DATAMAGE file you simply copy
- all the files in the sub-dir. That's harder.
-
- DATAMAGE files have their definition in two files: HEADINGS.SAD and KEY.SAD.
- The headings file has strings, maximum 25 chars, and the key file has three
- numbers in it's 33 byte records, ascii format. These files are read by the
- open_file function, and the DATAMAGE file structure is filled.
-
- From then on, the information about a particular field in a particular file is
- at hand in the structure. To find out if field four in file four is numeric
- you might go: if (fi [4].key [4] -> type > 1). fi is the file-info structure,
- subscript gets us file four (the FIFTH file loaded), .key gets us into the
- array of far pointers to structures defining the fields, -> type gets us the
- field type, which is defined in the code.
-
- So, the DATAMAGE isam provides you with the power to load and process ANY file
- created by/accessible to DATAMAGE. It's loaded with PRACTICAL features the big
- boys just don't have, like read/writing ANY individual file/field, instead of
- having to move seven thousand bytes to/from disk just to change one. And a
- window that allows the user to select a field in a file, etc, etc, etc.
-
- DATAMAGE ISAM - FORMAT AND PARTICULARS
-
- SPECS
-
- RECORDS IN FILE: 32,000
- FIELDS IN FILE: 200
- MAX STRING FIELD LENGTH: 35
- ALL NUMERICS DOUBLE PRECISION, MBF FORMATTED 8-BYTE STRINGS
- MAX INDEXES: 5
- INDEX MODES: UNIQUE, NON-UNIQUE, CROSS
- RECORD NUMBERS: MANDATORY, UNIQUE
- MAX FILES OPEN: 8
-
- RECORD NUMBERS
-
- Each record in a DATAMAGE file has a number. It may be 1 - 32,727. The number
- is stored in the file CTRLFILE.RAD. If the number is zero, the record is a
- "hole" and is available for use. No record number can be duplicated.
-
- FILE INDEXES
-
- DATAMAGE indexes are simple NUMBERS. The targeted string is turned into a
- signed word and recorded in the file: FILEINDX.RAD. The indexes have the
- capacity to hold five two-byte integers, so the records in the file are ten
- bytes long. This SIMPLE method offers INCREDIBLE speed in searching and
- updating, and is the easiest to understand BY FAR.
-
- SEQUENCING
-
- The first record in YOURDATA.RAD, the main datafile, is numbered by the first
- record in CTRLFILE.RAD and indexed by the first record in FILEINDX.RAD. So, if
- we were searching in FILEINDX and found something we liked, we would know that
- the record to read in YOURDATA.RAD would be the SAME sequence as the index
- record we now had. We could get a field out of it to compare, or even the
- whole record if we needed it.
-
- Likewise, if we went searching in the CTRLFILE.RAD and found a record number
- that struck our fancy, we would know that it's record was the SAME sequence in
- YOURDATA.RAD as the record number we now had from CTRLFILE.RAD.
-
- CUSTOMIZATION
-
- The ISAM is provided as SOURCE CODE. If you have a program to do that requires
- only two files open you may find it convenient to open the three associated
- files in each DATAMAGE file and just LEAVE them open during the program. Feel
- free to do so. The ISAM is set up to process eight files, and thirty-two files
- open is more than most folks allot for in their config.sys file, and would
- waste memory most of the time.
-
- In a program you have you want it to process one file, and ONLY one file. So,
- you won't need the show_datafiles function. You will pass a constant to the
- open_file routine. Feel free to REMOVE unused functions from your final
- version. There's no sense having un-used code.
-
- LAN OPERATION
-
- You will need to add your own record locking. May I suggest you read the
- file's record from the CRTLFILE.RAD file, multiply it by -1, and write it
- back? That way, the main record could be "read-only." Locked, but still
- readable. This bypasses the locking on the lan, and a LOT of grief!
-
- PROGRAMMING EXPERTISE
-
- I can but assume that you are a better C programmer than my humble self.
- I am just a hacker from Indiana who likes to punch these keys. Anyhow, you
- SHOULD understand C (if anyone REALLY does?) and have written random-file
- programs of your own, possibly incorporating an ISAM.
-
- If you are just learning C (aren't we all?) this AINT the place to start. If
- you are wanting to learn random-file processing and already know C you will
- find the code invaluable.
-
- Whatever your level of digital dexterity you are going to have to THINK to get
- this. There are remarks in the code, but they are "slim." You will need to
- read the function's code to figure out what global variables it takes as input,
- and changes as output. If I listed this you wouldn't read the code.
-
- NOTHING NEW
-
- After programming for a number of years I realized that the really BEAUTIFUL
- solutions all had only one common ingredient: SIMPLICITY. And the DATAMAGE
- ISAM, pretty or not, has a liberal dose of that. This is the way it's been
- done for YEARS, folks, on many a multi-million dollar mainframe computer.
-
- All I've done is to simplify it, adapt it to a PC, and add my indexing scheme
- which I thought about FOR YEARS while using convoluted and overhead-intensive
- alternatives. My way may be described as brute-force computing, but I, for
- one, can do without the errors that "finesse" often generates.
-
- DATAMAGE INDEXES - THE BRUTE FORCE THEORY
-
- As the hardware progresses BRUTE FORCE works better and better. Modern
- machines running at 20 Mhz with RLL controllers on FAST hard drives, possibly
- cacheted with smartdrv etc, might as well be SLOW ram. While other ISAMs are
- half-way up their B-trees I will have checked a thousand records with brute
- force. They say: "I'll find the last record as quickly as the first!" Isn't
- that like saying: The first record takes as long to find as the last?
-
- You may have noticed that the RAM_BASE program within DATAMAGE will find a
- record in a hurry. That's because it can load up to eight thousand record's
- indexes into 80K of ram. Then, it does index searches without bothering the
- disk drive. In this case, I will have checked FIVE thousand records with brute
- force before the B-tree is clumb.
-
- In either case, all I need to do to update an index is to decode the string,
- turn it into a number (routines supplied) then write it into the index file in
- the proper sequence. The write_MAGE_record function does this for you. And,
- from it, you can easily see how to do it yourself.
-
- BRUTE FORCE programming provides both the programmer and the computer a rare
- opportunity to run flat out. You don't spend a lot of time reasoning; that's
- not what a computer does well, and reasoning introduces the opportunity to err.
-
- Just target 10 bytes, gotten off disk or in ram, compare one or more of then to
- search values, repeat if not equal and not end of file. THAT's what a computer
- does: many FAST repetitions of some MINDLESS operation.
-
- BRUTE FORCE, when well-directed, often results in the lowest overhead to do the
- job. DATAMAGE indexes are just ten bytes per record, and can cover five
- fields; any/all of which can be unique or cross.
-
- I have often seen data "sets" (consisting on one or more files) in which the
- indexes took up FAR more disk space than the data. And the PROGRAMMING
- overhead often equaled/surpassed the actual procedure of the program and
- entailed linking in object files for which I had no code or using code I didn't
- understand and couldn't have fixed if my life depended on it. And, for what?
-
- GETTING STARTED
-
- In the first couple screens of the MAGEISAM file the structures: fi (defining
- DATAMAGE files) and finfo (defining fields within DATAMAGE files) are defined.
- Copy these definitions to a piece of paper, then load the MAGEISAM.C file into
- your compiler. Search for open_file. Read the function, while referring to
- the paper. Dig it. All the information on the loaded file is there, but YOU
- will have to write the if statements to check it, and your understanding of the
- ISAM depends on "C-ing" these structures.
-
- Once you "C" the open_file function the rest should become crystal clear.
-
- The open_file function uses two of it's own FILE *s. Such is not the case with
- the majority of ISAM functions. In any environment that has up to eight files
- open, requiring the use of three FILE *s each, there's going to be a shortage
- of IOCBs. And, it's FASTER to test a file to see if it's open than to (attempt
- to) open it. LOTS faster.
-
- So, then, HOW to test a file for open status? LOTS of ways to do that, too,
- Many of which involve linking in and calling yet another function. Got lots of
- THEM, now. I decided to set the file pointers in the fi structures to NULL
- during the load, then set them to NULL every time I closed them. That's EVERY
- TIME, hear? The first time you don't, you'll be SORRY!
-
- The ISAM functions test the files, then open/close them if they were closed.
- If you don't set the FILE * to NULL after closing a file the next ISAM function
- you call on that file will "think" it's open. NOT good. Not to mention trying
- to close it, when it's not open.
-
- A "cheapie" way around this is to use your own FILE *s. NOT recommended. Use
- mine. Like I said, they're in short supply. Let's say you have the main file
- open and you call write_MAGE_rcd. Stipulate further that there are no "holes"
- in the file, and a record is ADDED. But, it was added "to" the FILE * in the
- fi structure, which was closed. YOUR file pointer doesn't "know" it's there.
-
- What will actually happen is dependent on your DOS version, your controller,
- etc, etc. It's a chance you DON'T need to take. I have seen it corrupt the
- fat, (yeah, I make mistakes, too) and maybe it could do worse?
-
- THE files_loaded VARIABLE
-
- Every time you load a file you MUST increment files_loaded. And decrement it
- when you close it. It's defined in the first screen of code. If you wish to
- add this to the open_file function, by all means. But I sometimes read it off
- disk, then use it as comparitor for a for loop when loading files.
-
- If the files_loaded BYTE is set to a value not equalling the number of files
- open, expect trouble. The files are opened/closed IN ORDER. You COULD open
- file #8 first, but WHY? I never have, so I don't know if it will work.
-
- COMPILING
-
- The ISAM is contained in a module of code. Most all of it's functions are FAR,
- so that they can be called from other modules. This means you will need to use
- the medium memory module when compiling. NO, huge won't work.
-
- The ISAM calls many of it's own functions. These functions are in the same
- module as the calling function, but their definition requires them to be far
- calls. Far calls take longer than near calls, and occupy more code space.
-
- To rectify the catche-22 above, the linker has a /F option. This converts all
- far calls to functions that occur in the same module to near calls. Saves time
- and memory. To use it, type /F after link/qlink.
-
- WRAP-UP
-
- Yeah, I could have compiled it all to object files and simply made a list of
- functions, their parameters and returns. I always like to be different. YOU
- may have to do a little work, but you will actually understand the ISAM after
- you do. You can even change it, if you DARE.
-
- It's true that only a real programmer can understand the code. And, in my
- opinion, just as well. If you can't read and understand the code you've no
- business writing this kind of program in C.
-
- If you think you might, but avoid dis-appointment by not playing - you LOSE.
-
- If you're just plain too lazy to read the code and, thereby, understand it and
- be, therefore, able to modify it - you LOSE, too. But there are PLENTY of
- high-tech, object-file (and even tsr) ISAMs to fill your "need." And, all you
- have to do is to link them in, call them like THIS, and they return like THAT.
- You won't be able to access their files with DATAMAGE, though.
-
- It's fine, until you need to "call" them a way they don't call, or get a return
- they don't return. If you are satisfied with limiting your programs, in both
- scope and performance, to their capabilities then your standards are lower than
- mine. I like to take PRIDE in MY work.