Btrieve Developer`s Journal
Transcription
Btrieve Developer`s Journal
Btrieve DevelopersJournal ® October-December 1994 Vol. II No. 4 THEINDEPENDENTSOURCEOFNEWSANDINFORMATIONABOUTBTRIEVEANDSCALABLESQL BTI HOSTS THE SUMMIT Btrieve Technologies Reveals Ambitious Plans for 1995 Austin, Texas Over one hundred representatives of organizations which use Btrieve and Scalable SQL gathered in Austin in October to meet with Btrieve Technologies management and staff, and to discuss the plans the company has for the future. The two-day conference, organized by BTI, was designed ...to let our customers know about our plans, and to get feedback from them about what their needs are and whats important to them, said Ron Harris, president of BTI. During his opening remarks, he told participants not to be shy about asking questions, adding, All of our employees will be in and out of here during the course of these meetings, and if you dont ask us questions, you can bet that were going to ask you some. Summit participants included a diverse mix of accounting system vendors, corporate MIS departments, vertical market developers, independent consultants, and database tool vendors, some from as far away as Europe and the far east. Ron Harris mentioned the international aspect of the gathering in his opening remarks, and took the opportunity to introduce Patrick Duboisset, recently hired to lead BTIs European marketing division. The conference opened Monday, October 10, with addresses from Ron Harris and Nancy Woodward, BTI chairman. Nancy outlined the evolution of Btrieve Technologies from its inception as Softcraft, Inc., through the ownership by Novell, and the recent re-acquisition of the product line by Btrieve Technologies, Inc. She discussed BTI product introductions during the first six months since the reacquisition, the current relationship with Novell, and the companys strategy for positioning its products as cross-platform database solutions for middle-market database customers. One highlight of Nancys presentation was the announcement of Built on Btrieve, a market awareness program designed to See Summit on page 4... IN THIS ISSUE The Summit Btrieve Technologies holds a two-day conference in Austin, Texas with leading users of Btrieve and Scalable SQL to discuss current strategy and future plans..............Page 1 Inside Btrieve Doug Reilly reports on the internal structure of Btrieve version 6.x and focuses on several differences between v5 and v6................Page 8 Hands On Review Steve Mook takes a detailed look into the most common challenges users face when they attempt to access Btrieve-based data with Microsoft Access.....................................Page 13 BTIs Technical Corner Photographer:JamieProvenzano In another installment of Btrieve Technologies Technical Corner, we provide the latest technical information on Btrieve and Scalable SQL including how to optimize the new Btrieve version 6.15 engines.....Page 17 Btrieve and Scalable SQL users, BTI employees, and 3rd party vendors enjoyed the chance to meet face-to-face to discuss the future of BTI and their products. Seminars dealt with technical, marketing, and product support issues. Btrieve Accounting Eric Cohen, CPA and Computer Accounting Consultant, begins a three-part series on why Btrieve is the best, safest, and most widely used method for maintaining accounting data.........................................................Page 25 And much, much more... Volume II, Issue 4 ISSN 1071-7463, published quarterly by Smithware, Inc. Staff Publisher: Scott Smith Editor: Steve Mook Contributors: Jon Burke, Eric Cohen, Jim Fink, Ray Kukari, Doug Reilly Contributors to Technical Corner: Linda Anderson, Doris Eldridge, Mad Poarch, Carol Rylander Graphic Design: Arthur Austin Design Consultant: Tania Owen Studio Photographers: Dean Dixon, Jamie Provenzano Illustrators: Will Owen, Albrecht Dürer Advertising Manager: Carolyn Lighty Circulation Manager: Cindi Gourley Subscriptions Annual subscriptions are for four issues per year at $49/year for delivery inside the United States, and $79/year for delivery outside the United States. Back Issues: Back issues are available for $20.00 per issue. Contact Cindi Gourley at (615) 386-3100 for additional information. How to Contact BDJ You may address news items, new product announcements, tips, advice, comments, complaints, praise, or any other correspondence to: Btrieve Developer's Journal 2416 Hillsboro Road, Suite 201 Nashville, Tennessee 37212 Telephone: (615) 386-3100 Facsimile: (615) 386-3135 CompuServe: 73173,2731 MCI Mail: 590-5654 Internet: [email protected] Advertising For information about advertising your product or service in Btrieve Developer's Journal, call Carolyn Lighty, Advertising Manager, at (800) 685-2403 or (201) 7120044. Copyright 1994 by Smithware, Inc. All rights reserved. With the exception of the “Technical Corner” section, this publication is produced independently of Btrieve Technologies, Inc. No part of this publication may be reproduced in any form by any means without permission in writing from the publisher. Smithware is a trademark of Smithware, Inc. Btrieve and XQL are registered trademarks and Scalable SQL, Xtrieve Plus, and Microkernel Database Engine are trademarks of Btrieve Technologies, Inc.All other names are the trademark of their respective manufacturers. From the Publisher... 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 1234567890123456789 As we at Smithware celebrate the first anniversary of Btrieve Developers Journal, I want to sincerely thank all of you who have supported our publication through your subscriptions, input, collaboration, and comments. When we published our little 8-page premier issue in late October of last year, we had no idea what a tremendous void BDJ would fill. We also could not have predicted that the movement of the Btrieve product line would accelerate with such force. The end of a year always causes me to seriously consider the future... This time, I find myself thinking about those things that, in my opinion, BTI must do in the coming months in order to maintain and build on their leadership position in the middle market. The following is my proposal of these things. They must continue to move the Btrieve Microkernel Architecture to new platforms quickly. In addition to having a SCOTT A. SMITH, PUBLISHER Btrieve engine as a database server on Microsoft NT, BTI will move into other areas as well. These areas will include IBM LAN Server, UNIX implementations, and PIN (Processor Independent NetWare) versions of Btrieve running on diverse platforms. They will heavily promote the proven scalability of the Btrieve product line. BTI will show the market that Btrieve truly is the only database manager that runs consistently and manageably from a one-user installation on a lap-top PC, to ten users on a LAN, to a thousand users on a WAN. They should aggressively pursue the international market. Look for massive BTI organization, marketing, and fulfillment throughout Europe and look for a Btrieve subsidiary operating in Japan by Mid-1995. They will mobilize their marketing team to help develop and promote more robust and powerful third-party tools (yes, including Smithwares line) by creating and strongly promoting a Built on Btrieve product identification and certification program. This program will help users of Btrieve-based applications take advantage of the Btrieve tools that are already out there, and will expand the market for us as third-party tool vendors. Also, look for a strong BTI commitment to ODBC at the beginning of the year. No one can truly predict the future, I suppose... So lets look at this list again in a few months to see how Im doing. PhotographbyDeanDixon BtrieveDevelopers Journal Contents... Inside Btrieve Inside Btrieve 6 Files By Douglas J. Reilly Technical Corner 8 What has changed inside Btrieve since the release of the version 6.x file structure? More than you think! Btrieve Applied Getting a Handle on Btrieve By James H. Fink 10 Developing applications in C just got easier: Use Jims stdio-like method for Btrieve access in C and you wont regret it. Technical Supplement to BDJ Btrieve Technologies, Inc. Learn how to optimize Btrieve 6.x, hear details about what in store for the future of the Btrieve Microkernel, and get the latest tips available from BTI. Accounting Btrieve Based Accounting By Eric E. Cohen By Steven A. Mook 25 Heres the first of a three-part series on Btrieve and Accounting systems. Feature Article Hands-On Review How to Make Microsoft® Access 17 13 The connection between Microsoft Access and Btrieve can be difficult. Steve simplifies the process by answering common questions. Programming for Hire By Jon Burke 31 From the both the clients and the contractors point of view, Jon looks at the ins and outs of computer consulting services. The SUMMIT continued from page 1 build end-user awareness of products which use the Btrieve and Scalable SQL data management systems. BTIs cross-platform strategy currently includes workstation support for DOS, Windows, OS/2, and server support for NetWare, and BTI recently announced that it is developing a Windows NT server in conjunction with Microsoft. Other possible platforms currently under review are workstation support for Macintosh and server support for OS/2, UNIX, and PowerPC. Doug Woodward, BTI chief technical officer, followed Nancy with insights into the direction of the product line and the Microkernel architecture. Details of Dougs presentation are included in The Future of the Microkernel article in this months Tech Corner on page 19. The conference included several seminars on the technical and business aspects of the new company. The Scalable SQL product overview and feedback session led by Bo Holland, BTI product marketing director, touched on licensing issues and technical questions from developers. Questions and comments from the audience followed, with a consensus that ODBC support was important if not from a development standpoint, at least certainly from a marketing standpoint. The discussion ultimately centered on the challenges developers and users face when trying to migrate data from non-relational legacy applications to relational systems, such as issues of data definition and security, mission critical application performance, and data conversion. Carol Rylander, Btrieve product manager, led a session on Btrieve which dealt primarily with the new licensing structure and the planned improvements to the Microkernel. The scheduled after-dinner keynote address on Monday evening, The Info Bond: A View from a Pothole, unfortunately had to be canceled when Rick Segal, multimedia evangelism manager for Microsoft Corporation, was unable to attend due to illness. Conference attendees instead spent the evening visiting Austins historic Sixth Street, talking with colleagues and BTI employees, and watching several hundred thousand bats stream from their nesting site under the Congress Street bridge. Tuesday meetings dealt primarily with business and marketing issues, 3 Btrieve Developer's Journal including an announcement by Lori Baldwin, BTI channel marketing director, of proposed reseller programs, and training and certification programs for VARs and consultants. Mad Poarch, VP for customer relations, presented a seminar on BTIs proposals for fee-based technical support options, and distributed a questionnaire soliciting comments and customer feedback. This questionnaire was also posted on the CompuServe BTRIEVE forum so that customers who did not attend could add their input. The meeting ended with a question and answer panel discussion with Ron Harris, Doug and Nancy Woodward in which the panel addressed questions submitted by attendees throughout the course of the conference. Reaction to the Summit was generally very positive. Most of the conference attendees considered BTIs willingness to share strategy and solicit feedback to be a helpful and refreshing change from the way in which many of their suppliers do business, and most appreciated the opportunity to meet with their colleagues and with BTI staff. BTI officials said that based on the positive feedback from the first meeting, more Summit meetings will be planned for the future. ² Duboisset to Head BTI Europe Austin, Texas BTI has appointed Patrick Duboisset, a former Novell executive in Europe, to the post of Director of European Market Development. Patrick will be responsible Patrick Duboisset for positioning and supporting BTI in Europe. He will work to strengthen distribution channels with valueadded partners in all sectors of BTIs relationships abroad, said Laurie Wisbrun, a BTI representative. Patrick was with Novell in Southern Europe from 1989 through 1993 where he was responsible for increasing Novells market share from 40 to 65% throughout the region. According to Mr. Duboisset, My ambition is to build strong distribution partnerships, and identify and appoint authorized solutions integrators, and to make BTI the industry de facto standard in the departmental database engine market. NewsBriefs BDJ Executes Distribution Agreement in Japan Nagoya, Japan An agreement to distribute Btrieve Developers Journal to the Japanese market has been executed between Smithware, Inc., publishers of BDJ, and AG-Tech Corp., the leading supplier of Btrieve support and services in Japan. According to Steve Mook, Smithwares Vice President for Development, We are pleased with AG-Tech Corps decision to become involved with our magazine because we recognize the vast global support that Btrieve enjoys, particularly in Japan. AG-Tech will provide additional material pertinent to the Japanese perspective in the copies of BDJ that they distribute. For additional information, contact Smithware at (615) 386-3100 or AG-Tech Corp. in Japan at (052) 951-2706. Synex Systems Readies @Trieve for Excel Vancouver BC, Canada The leading manufacturer of spreadsheet links for Btrieve files, Synex Systems, is preparing to release a new version of @Trieve for Excel. @Trieve hot links data from any indexed Btrieve file directly into an Excel sheet through the use of commands, functions, and macros on a read-only basis. If a user sets up Excel sheet templates with @Trieve, it is then possible to pull live data into Excel at any time with the click of a button. @Trieve is compatible with:local and requester versions of Btrieve 5.x, 6.10, and 6.15, and with Excel versions 4 and 5. Additional functionality may include a file query command to assist users in pulling data via dialog screens with the option of saving these queries as macros, and enhanced screens for specifying index requests. Contact Synex Systems for additional information at (800) 663-8663 or (604) 688-8271, Fax: (604) 6881286, BBS: (604) 688-2351, or GO SYNEX on CompuServe. Vol. II, No. 4 October-December 1994 (800) 828-7438 or (615) 386-3100 FAX: (615) 386- Briefly Noted Business Tools, Inc. (919-932-3068) has announced the release of TAS Professional version 5.0, the latest release of their popular modular design environment for accounting and business information systems... Solomon Software (419-424-0422) announced that both of its accounting product lines, Solomon IV for Windows and Solomon III for Btrieve, will be available on Microsoft Windows NT Server 3.5, as well as on Novells NetWare. The company announced that Solomon IV Server Edition, which runs on Scalable SQL, also will be available on Windows NT Server. Solomon also has introduced a multimedia demonstration CD-ROM of their Windows-based accounting software... Btrieve Technologies Inc. (512-794-1719) is looking for beta sites for the Windows NT Btrieve engine. Send company name, address, contact name, CompuServe account ID, and the timeframe in which you are available to actively test the beta software to the BTI CIS account, 74431,3337. The Btrieve for OS/2 v6.15.1 pre-release is now available in the CompuServe BTRIEVE forum to anyone who wants to try it out. You may provide feedback in forum section 13. This pre-release may contain some areas of functionality which have not been perfected... Magic Advisor International (301-7794709) has been formed to publish a new magazine entitled MagicCom, the Magic Communications Magazine. The bimonthly publication features articles of interest to developers who use the Magic development tool from Magic Software Enterprises. Subscriptions are $49/year in the US and Canada and $99/year elsewhere... IQ Software Corporation (404-4468880) is shipping their new IQ for Windows version 4.0. IQ is a clientserver query and reporting tool that supports many databases including Btrieve and Scalable SQL... 4 Btrieve Developer's Journal MICROSOFT-BTI ANOUNCE PACT Agreement to Deliver Client-Server Btrieve Database Engine for Windows NT Atlanta, Georgia Microsoft and Btrieve Technologies, Inc. (BTI) announced an agreement to deliver and jointly market the Btrieve database engine for the Windows NT Server operating system. Under the terms of the agreement, the two companies have agreed on a broad set of joint marketing programs that are intended to introduce Btrieve and Windows NT customers to the benefits of the combined technology. The joint agreement was announced as part of a keynote address delivered at NetWortd+Interop by Jim Allchin, vice president, Business Systems Division of Microsoft, and Ron Harris, President and CEO of Btrieve Technologies. As part of this agreement, Microsoft will include a coupon in every package of Windows NT Server that can be redeemed for a ten-user version of the client-server Btrieve database engine for Windows NT for a promotional price of $99. After one year, BTI plans to offer an attractively priced, shrink-wrapped package of Windows NT Server and Btrieve through its distributors. “This agreement makes it easy for Btrieve customers to get the scalability, portability and reliability of Windows NT Server,” said Allchin. “Customers using the many applications built on Btrieve for industries including insurance, banking, health care, manufacturing and accounting can now adopt Windows NT easily.” In April of this year, BTI acquired Novell’s database product line and began aggressively investing in new marketing, sales and development programs, including the expansion of the product line to new platforms. This is the first announcement of BTI products available for Windows NT. “The combination of Btrieve, Windows NT Server, and the Visual Basic programming system provides a powerful platform to meet the growing needs of small, medium, or departmental organizations,” said Ron Harris. “The agreement is a big win for the more than one quarter-million sites in North America Vol. II, No. 4 October-December 1994 running business-critical Btrieve applications today.” With this announcement, Microsoft and BTI officials confirmed that Btrieve applications can now automatically scale from mobile laptops or notebooks to large client-server configurations with symmetric multiprocessing hardware without changing a line of application code. Production shipments of Btrieve for Windows NT are scheduled to begin by the first quarter of 1995. ² Crystal Reports 4.0 Released Vancouver BC, Canada Crystal has announced major new versions of Crystal Reports and the Crystal Reports Server. We have increased the speed dramatically, said Greg Kerfoot, President of Crystal Services and Director of R&D. We have also provided the end user with the ability to get the information they require with the Crystal Reports Server 4.0. Crystal claims that thier totally re-designed report engine with Smart Engine Tecnology greatly increases performance over previous versions, with reports being generated 2-10 times faster than before. Crystal Reports version 4.0 also includes Experts, which prompt users for choices, and then do reporting tasks for them automatically. Improvements to the user interface include a new tab interface, ruler, Best Fit button, automatic styles, and a new grid with on/off and visible/ invisible options. The version 4 release also adds 20 new direct-call functions to the developer interface of its report engine, and has added a new OCX object in addition to its Visual Basic VBX interface. Contact Crystal Services at (800) 877-2340 or (604) 681-2934. (800) 828-7438 or (615) 386-3100 FAX: (615) 386- copy that is not current. If the change is made successfully, the counters are changed and Btrieve will know which file control page is correct. If the change is not completely written, no harm is done, since the file control page will still be the copy that was correct before the change was begun. Halt! What file type goes there! Inside Btrieve 6 files By Douglas J. Reilly, Access Microsystems, Inc. When I first mentioned to the folks at Btrieve Developers Journal that I wanted to take a look at some of the differences between Btrieve version 5.x files and version 6.x files, I had no idea how great the differences between the two file types would be. Was I in for a shock! For details of the version 5.x format, I refer you to Special Assignment... Btrieve File Recovery in the JanMarch 1994 BDJ (Vol. II, No. 1). One of the major changes in how Btrieve works for Version 6.x is the elimination of preimaging files which were used in prior versions of Btrieve to maintain file integrity. In Btrieve version 5.x, before changes were made to the Btrieve file, the original pages were written to a file with the same name as the Btrieve file, but with an extension of .PRE. It is for this reason that you were never to create Btrieve files that had a file name that differed only in the extension (for instance ORDER.HDR and ORDER.DET). Btrieve 6.x files do not create pre-imaging files, however the naming restriction remains the same, since Btrieve does in some cases (continuous operation) create special files with extensions of .^^^. How does Btrieve version 6 ensure that information is properly written or restored? This brings us to the first major change in the internal structure of Btrieve files for version 6. Look at figure 1. This shows beginning of the first page of a Btrieve file in a hex I had no idea how editor. Note that the first two characters on the great the differences page are 4643 hex (the characters FC, I between Btrieve version 5 assume for File Control). All pages in and 6 would be. Was a Btrieve file now have some identifier in the I in for a shock! first two bytes. The most fascinating thing about the file control page is that there is another instance of that page directly following it. This is where it gets interesting. On each of the file control pages, there is a counter that is checked by Btrieve to allow it to determine which copy of the file control page is current. When changes are made, they are made to the 5 Btrieve Developer's Journal An interesting side trip is in order. On several occasions, I have had Btrieve developers who wished to determine if any arbitrary file was a Btrieve file. After I attempted to get them to simply try and open the files using Btrieve, I was able to give some answers for version 5.x files, but they were at best hints and rules of thumb. What follows is a fairly surefire way to determine the if a file is a Btrieve file. First, check the length of the file. If it is not divisible by 512, forget it. This is not a Btrieve file (or it could be a very badly or strangely damaged Btrieve file). Next, open the file in binary mode and read the first 10 bytes. The first 4 bytes will be 46 43 00 00 hex. Next, look at the tenth byte. This should be an even number between 2 and 16 inclusive. If not, this is not a Btrieve 6.x file. This is the number of 256 byte blocks in the page size. Calculate the PAGE_SIZE (if 2, PAGE_SIZE=512, if 4, PAGE_SIZE=1024) Next, read the 4 bytes exactly PAGE_SIZE bytes from the beginning of the file. These four bytes must also be 46 43 00 00 hex. If they are, you can be reasonably assured that it is a Btrieve 6.x file. Page Allocation Table (PAT) Pages After the file control pages, there is a new type of page in Btrieve 6.x: Page Allocation Tables, or PATs. The only reason this may sound familiar to some of you is that BUTIL may have reported to you that the PATs are damaged. What exactly do these PAT pages do? Look at figure 2 to see the first portion of a PAT page. Like File Control Pages, PAT pages come in sets of two. Just like the File Control pages, the PAT pages have a usage count used to determine which of the pages is the current good PAT page. Perhaps even more interesting is the fact that there exists a second way that Btrieve can use to determine which PAT page is the current PAT. There is a 32 bit bitmap (I believe in the FC page) that Btrieve can use as a reality check to ensure that the correct PAT is in use. Those database folks out there may have already noticed a potential Figure 1 - The Beginning of the First Page of a version 6.x Btrieve File Vol. II, No. 4 October-December 1994 (800) 828-7438 or (615) 386-3100 FAX: (615) 386- When I was first poking around with Btrieve 6.x files, the first thing I wished to determine was the layout of records within the data pages. This is important to me as the developer of recovery utilities that sometimes go the extra mile beyond simply using Btrieve calls to do the file recovery. In some cases, I would simply go from page to page, searching for possible data pages by trying to set the record position (using the SET_POSITION operation code 22) to the first slot on a page and testing for status 43 (invalid positioning). If I got a 43, I assumed the page was not a data page and moved on, otherwise, I tried every possible record start position on the page, based upon what I knew about the record length and the number of keys that allowed duplicates. The number of keys that allowed duplicates was important because pointers to the Figure 2 - Page Allocation Table Page previous and next record for each duplicate key had to be stored. For details, I once again refer you to Special problem with this scheme: Forgetting for a moment what you Assignment... Btrieve File Recovery in the Jan-March 1994 have to do when your 32 bit bitmap is filled up (it sure sounds BDJ (Vol II, No. 1). ugly to me), what is the rule for data stored twice? Thats When I started looking at the pointers, it was correct! If data is stored twice, there is a good chance that it apparent to me that something was different. The pointers did will be stored incorrectly in one of those places. The folks at not seem to be quite right. For example, look at figure 4. At BTI recognized this as well, and removal of this bitmap is one offset 3356 there is a pointer to a next or previous record (I of the minor changes between am not certain which as I write the 6.10 Btrieve NLM/Requester this, but I assume it is a next and the 6.15 file format. pointer). Because of the way The first two bytes on numbers are stored in Btrieve the PAT pages are 5050 hex (or files (not Intel format) the hex the characters PP, perhaps for numbers 00002005 represent hex PAT Page). After some header 520 or decimal 1312. This is information, the PAT page from a 512 byte page size consists of many 4-byte pointers Btrieve file, and so we know that to pages within the file. this cannot be a direct pointer, Actually, the pointers are 3 since the four pages allocated to bytes, since one of the bytes is FC and PP pages mean that as a used to indicate what type of direct pointer using the page is pointed to by the beginning of the file as a basis, it Figure 3 - Data Page pointer. Looking carefully at would point into the first of the figure 2, notice that at offset PP pages. Then I tested the offset 1549 there is a character D (hex 44). This tells us that the from the end of the FC and PP pages, 512 times 4 (for the 4 page referred to by this particular pointer is a data page. FC and PP pages) plus 1312, gave me 3360. 3360, as you can (Other known values that can be embedded into the pointer see in figure 4, is the byte hex 01 just before the next record are A for Alternate Collating Sequence, V for Variable tail begins, and so the mystery was solved. The previous and next data, and any value over hex 80 for indexes, with the a page pointers were pointers from just beyond the FC and the PP for index 0 being denoted by a value of hex 80, a page for pages. At first I thought this might just be a way to get index 1 being denoted by a value of hex 81, etc.) At offset slightly beyond the 4 gig limit on file size, but then the 1550, notice the hex value 06. From this we know that the page that this pointer refers to is at offset 6 times the page size (in this case, 6 x 512, or 3072). Sure enough, as we look at figure 3, we find at offset 3072 what looks like a data page. The number of pointers varies with the page size. Take the page size, divide it by 4, subtract 2 for some header information on the PAT pages themselves, and you have the number of page pointers you can find on a given PAT page. For instance, if the page size is 4096, divide that by 4 and you get 1024. Subtract 2 and you have 1022. So, from this, we know that in a file with a page size of 4096, each PAT page contains pointers to 1022 pages, or 4,186,112 bytes of data. This is, of course, far short of the current stated limit for Btrieve files of 4 gig. How does Btrieve keep track of Figure 4 - Another Data Page additional pages? Therein lies a tale... (800) 828-7438 or (615) 386-3100 FAX: (615) 386-3135 limitation to the PP page setup Vol. II, No. 4 October-December 1994 sank in. Since a single PP page Btrieve Developer's Journal mechanism to allow multiple PP pages. If pointers are based upon distance from the PP page that a particular page reports to, this could have the effect of eventually (when ported to an operating system that supports it) removing Btrieves 4 gig file size limit. Very neat indeed! Getting back to my immediate problem, that of trying to recover data from badly damaged files, one thing that had served me well in the past was to simply eyeball the file and from that determine where data would be. It soon became clear that this was not going to work with Btrieve version 6.x files. For example, if I add a single record to a Btrieve 6.x file, it will appear neatly once in the file. However, if I then add a second record to the file (assuming that the record does not take up an entire page), you will find that there are two instances of the first record in the file: The original instance, on a page by itself, and another copy on the page where the second record has been added. It appears that Btrieve writes the new page (with both records) and if all is well, commits the new page, but does not obliterate the old page. This is important, because if you are writing a grungy routine to salvage records from a damaged file, you may well get much more than you bargained for. The issue is even more confusing when rather than entering a new, second record, you are simply editing the first record. Then determining which page is the good page is even more complex. This has required a bit more study than I had originally anticipated, but rest assured that a coherent strategy for getting at the real data will appear in my next Inside Btrieve column. In order to see what type of error will give a PAT error, I got out my trusty hex editor and purposely messed up the file in several ways: I changed the values of pointers on the PAT page (making sure I was using the copy of the page that was currently good). I changed the D embedded in the pointer to indicate that the pointer pointed to a data page to a Getting a Handle on Btrieve by James H. Fink, The PROMPT Corporation Using the Btrieve application interface for the C programming language can be an error prone and frustrating experience, even for experienced programmers who are familiar with the Btrieve API. The integer function BTRV() which 7 Btrieve Developer's Journal Q (a value I am not sure would ever be valid). Much to my surprise, BUTIL -SALVAGE never reported an error. My programs could still read and write the file, and even more of a surprise, after the write to the file, the PAT page was healed. All the bogus values I placed in the PAT page were now replaced with the proper values. Very strange! In fact, while I know that PAT errors occur, and I am fairly sure I know what should cause them, I am thus far (using Btrieve 6.15 for DOS) unable to cause one to occur. Like the previous problem (and it IS a problem if you cannot cause a failure to occur as you would expect), I anticipate I will be able to resolve this over the next several weeks. To be Continued... The scope of the internal changes to Btrieve version 6.x files has been a surprise to me. BTI has done many wonderful things with the Btrieve file format, and yet has managed to allow old programs to continue to function. This is the beauty of detail hiding. Next time, we will continue to expose some of the details of Btrieve file internals. I dont expect you will need to use (or should use) the gory details to do the bulk of your work, but these details can be critical when that call comes telling you that a catastrophic failure has occurred on a critical Btrieve file, and that week-old backup just wont do. ² Doug Reilly is the owner of Access Microsystems Inc., a software development house specializing in C/C++ software development, often using Btrieve as a file manager. He has had articles on Btrieve published in Dr. Dobb's Journal and is also the author of BTFILER and BTVIEWER Btrieve file utilities available on CompuServe. Dougs CompuServe address is 74040,607 and can be contacted at 404 Midstreams Road, Brick, NJ 08724 or at (908) 892-2683. provides all access to the Btrieve record manager, has 6 parameters, and arguments for all 6 must be provided regardless of the Btrieve record operation being invoked. But, depending on which of the 35 operations the programmer is invoking, the content and use of the arguments changes. Some of the arguments involve complex type casting, and others are buffer lengths that may vary over time. If an error is made when providing an argument, Btrieve error messages are often cryptic, and sometimes misleading, causing frustrating debugging sessions. Use of the BTRV() function for even the simplest processing of a table provides ample opportunity for error. To sequentially process a table on an index, the programmer has to open the table, get the first record, repeatedly get next records, and close the Btrieve table. A minimum of 24 arguments must be correctly supplied to successfully complete this task. This article will explain a method of dealing with these problems so that the application programmer can concentrate on using Btrieve to solve his or her application problem. The method uses a model that will be familiar to all C programmers --the stdio model. When processing a file using stdio, the programmer communicates with the file system using an integer handle or a pointer to the file provided by stdio that minimizes the chance for error by limiting the frequency with Vol. II, No. 4 October-December 1994 (800) 828-7438 or (615) 386-3100 FAX: (615) 386- which the programmer must specify information. An Example Figure 1 demonstrates how this method achieves the goals of reduced program complexity when accessing Btrieve tables. It depicts a fragment of a program designed to sequentially access a table. The program will process an insurance policy table from the first record to the last on index 0, in read-only mode. #include "bt.h" //the btrieve handle access routines //structure for policy table record struct POLICY_REC { char PolicyNum[7]; char PolicyData[93]; }rec; Figure 2 - The BT_FILE structure A word is in order about the field SQL_name. This method was implemented in a Novell 3.12 production environment supporting multiple Btrieve tables of 1 GB or more, using NetWare SQL. These tables frequently change location due to space constraints. To accommodate this, we established the convention of the Table Directory table which is always located on the SYS: volume in a particular directory. This table contains the SQL name of the file (such as Policy in SELECT * FROM Policy) and its current full path name. This approach allows for a significant measure of device independence, as will be demonstrated below. //structure for policy table key 0 struct POLICY_KEY0 { char PolicyNum[7]; }key; int main(int argc, char** argv) { Handle policy; //Handle is a typedefld int //inititalize table with the SQL name "Policy" //rec is the data buffer, key is the key buffer policy=bt_init("Policy", BT_readonly, 0, rec, key); } typedef struct BT_FILE { int handle; //the handle for the table char SQL_name[20]; //optional table used in SQL queries char full_path_name[64];//full path name of table int open_mode; //readonly, readwrite, etc. int index; //the index int status; //last status code returned for table char* data_buffer; //pointer to the buffer for the table int data_length; //the length of the data buffer char posblock[128]; //Position Block int opcode; //the last opcode used for the table char* key_buffer; //pointer to the key buffer int key_length; //the length of the key buffer; long record_count; //total recs in table at open time } bt_file, *pbt_file; //get the first record bt_getfirst(policy); Initializing the Structure do { //process each record } while (bt_getnext(policy) != BT_eof); To support this method, I developed the concept of initializing a Btrieve table. Normally, when processing a table, one need only open it. Initializing a table initializes the BT_FILE structure, opens the table, and does a stat operation on the table. Figure 3 shows the function prototype for bt_intialize(). bt_close(policy); int bt_initalize(char* SQL_name, int open_mode, int index, char* databuffer, int datalength, char* keybuf, int keylength); Figure 1 - Btrieve programming using the stdio model. The Approach Figure 3 - Prototype for bt_intialize Figure 2 shows the typedef declaration of a C structure, and a pointer to that structure, which I used to implement this method. The approach is to allocate and fill one of these structures for each unique Btrieve table access path (i.e. table and index) required by a program. The function doing the allocation will assign the structure a unique integer handle, and return that handle to the caller. Thereafter, the caller invokes Btrieve record operations by specifying the operation and the handle. Included in the method is a means of soft coding the location of Btrieve tables so that they can be moved and located at run-time without recompilation. The structure and its associated functions are partitioned in such a way that the programmer never directly deals with the structure. The only way the programmer changes the structure is with the associated functions. (800) 828-7438 or (615) 386-3100 FAX: (615) 386-3135 This function searches the Table Directory table for the SQL_name, captures the current full-path name of the file, dynamically allocates and constructs the BT_FILE structure, opens the table, does a stat operation on the table, and fills in the number of records on the table. If successful, the function returns a positive integer handle which will be used for all subsequent access to the table. In practice, calling this function proved tedious as structure addresses had to be cast to character pointers. To provide relief, I devised the macro bt_init shown in figure 4. //bt_init macro use to simplify calls to bt_intialize() function #define bt_init(SQL_name, mode, index, buffer, keybuffer) \ bt_intialize(SQL_name, mode, index, (char*)&buffer,sizeof(buffer)\ (char*)&keybuffer, sizeof(keybuffer)) Figure 4 - bt_init Macro Vol. II, No. 4 October-December 1994 Btrieve Developer's Journal This reduced the number of arguments required to initialize a Btrieve table from 7 to 5, as the macro computed the lengths of the data and key buffers and performed the appropriate type casting. Practice also revealed that there were times when we wanted to open a table not identified in the Table Directory table, so I developed a hard initialization function to allow the programmer to provide the full-path name of the Btrieve table to be processed. Accessing the Table Once a handle has been obtained, all subsequent access to the table is greatly simplified. The function bt_access(), prototyped in figure 5, manages all record operations for the table. The bt_access function takes as parameters the handle and the record operation code. It then looks up the BT_FILE structure allocated for that handle to collect all the data necessary to complete the requested record operation, and executes it. Some operations require that additional information be placed in the key buffer or data buffer. For example, a Get Equal operation requires a search argument in the key buffer. In these cases the programmer simply places the data in the appropriate buffer before invoking the bt_access() function. The integer returned by the bt_access() function is the Btrieve return code. Error Handling and Status Reporting To provide easy error handling, I established a global Boolean variable, bt_robust. This variable may be set or reset at any time. When this variable is TRUE, Btrieve error conditions encountered by the bt_access() function are returned to the caller. The caller can then deal with them as needed. When this variable is FALSE, the program will halt and issue an appropriate error message. This is useful in the early development stages so that energy is directed at building the application, not error handling. Certain ambiguous errors, for instance a duplicate key while inserting, are always returned to the caller for processing so that the programmer can determine within the context of the application if an error has actually occurred. To aid in status reporting, I established a global integer variable, bt_status. The last status code returned by Btrieve is always placed in this variable, so that status checking can be delayed. In Conclusion The simplicity, readability, and focus of this method as compared to the use of the standard BTRV() function speaks for itself. The method is also easily adaptable for a C++ implementation. ² int bt_access(int handle, int opcode); Figure 5 - bt_access Prototype Once again, it proved tedious to remember and supply all 35 opcodes, so I defined manifest constants and mnemonic macros for each of the principle record operations, as shown in figure 6. #define BT_geteq 5 #define BT_getfirst 12 #define bt_geteq(handle) bt_access(handle, BT-geteq) #define bt_getfirst(handle) bt_access(handle, BT_getfirst) //etc. etc. Figure 6 - Mnemonic Defines Closing Up The function bt_close(handle) closes a table, and returns the memory allocated for its BT_FILE structure to the heap. A happy by-product of this approach was the function bt_closeall(void), which allowed the programmer to be certain that all tables were correctly closed and memory returned to the heap, without any special coding techniques to track which tables might be open or closed. This was particularly useful for handling ABENDs occurring in the middle of opening multiple tables. The ABEND is handled by issuing a bt-closeall(), and exiting. 9 Btrieve Developer's Journal AcquiringtheSoftware Building and testing the software to implement this approach should take you less than a week. The author recommends doing so if you want to learn the ins and outs of Btrieve. If you would like to acquire the source code, object code, library, and documentatation for his implementation of this method, including a full function dynamic memory manager and linked list processor suitable for compilation by Microsoft C version 6.Oa through Microsoft C 8.0, kindly remit $50.00 to: The PROMPT Corporation 90 Mill Street Lincoln, MA 01773 Please specify 3.5" or 5.25" format. Vol. II, No. 4 October-December 1994 (800) 828-7438 or (615) 386-3100 FAX: (615) 386- How to Make Microsoft Access ® A short, practical guide up the slippery slope. by Steven A. Mook, Smithware, Inc. Email: [email protected] CompuServe: 71660,2746 Experience has shown that Microsoft Access is a very powerful database query tool. Experience has shown that Btrieve is a very fast, very reliable database engine. And experience has shown that hooking the two together is rather like bringing elephants over the Alps. Once you get to the top, all you need is a really big sled. The trick is in getting to the top. The questions used in this article were adapted from messages posted on the CompuServe MSACCESS support forum from July through October 1994, and they represent some of the more common pitfalls. Access returns Unexpected error from external database driver [20] whenever I try to attach to Btrieve. As with the other Unexpected error from external database driver errors, the number in brackets is the actual status number returned by Btrieve. Which means that you have at least one piece of Btrieve for Windows out there to return a status. But do you have the right piece, or enough of the pieces? Microsoft Access requires a Btrieve for Windows engine in order to open Btrieve files. Status 20 indicates that Btrieve for Windows is not loaded. As often as not, this error message means you simply dont have a Btrieve engine for Windows. Microsoft pulled it from the Access box shortly after the release of version 1.0, following a license disagreement with Novell, which held the copyright at that time. Application programs which run in DOS dont use the Btrieve for Windows drivers to access their files. They make record requests to a terminate-and-stay-resident (TSR) executable program in DOS, BTRIEVE.EXE, but this program is not accessible to Windows applications. There is also a clientserver version of Btrieve which runs on Novell NetWare, which allows server-based access to files on NetWare drives. Workstations on the network accessing these data files run a TSR called BREQUEST.EXE. This requester transmits requests for information to Btrieve running on the NetWare (800) 828-7438 or (615) 386-3100 FAX: (615) 386-3135 server as a NetWare Loadable Module (NLM), receives the results from the server process, and passes them back to the application. Btrieve for Windows also has both a local and a clientserver implementation. The local implementation is required to process any files not accessible to a server process (such as files on a local hard drive as opposed to files located on a network server running NetWare Btrieve). Local Btrieve for Windows version 5.10 is implemented as a dynamic link library called WBTRCALL.DLL, or WBTRLOCL.DLL if configured to run in conjunction with the NetWare client-server version of WBTRCALL. The size of this file is about 51K bytes. It links directly to the application and performs all Btrieve file I/O. The new Btrieve Client Engine for Windows, version 6.15, is implemented as a Windows executable program called WBTR32.EXE. There is still a WBTRCALL.DLL, but it is much smaller than the Btrieve version 5.10 DLL, as it does not handle any file I/O itself. WBTRCALL.DLL determines whether a Btrieve request should be routed to the local or to the server engine based on settings in the configuration file BTI.INI. WBTRLOCL.DLL acts as an interface between the requester interface, WBTRCALL.DLL, and the Btrieve for Windows Client Engine, WBTR32. Until Btrieve Technologies releases a true DLL requester for Windows, BREQUEST.EXE remains a critical link in the Windows implementation of NetWare client/server Btrieve. WBTRCALL.DLL routes requests for server-based data from the application to BREQUEST via a DOS Protected Mode Interface (DPMI). The client/server WBTRCALL.DLL will attempt to pass requests for local data on to the WBTRLOCL.DLL for processing, either internally (in version 5.10W), or via WBTR32 (in version 6.15). The key to this error is simply that you must have Btrieve on your system where it can be loaded by Access. Though you may have DOS applications which can access Btrieve files, you may not have what you need for a Windows application to access those files, as the DOS and Windows Btrieve client engines are different. If you have a Novell network, then you do have the Windows run-time engine for Btrieve as well, but Btrieve must be loaded and configured properly as an NLM on your server, and BREQUEST must be loaded prior to Windows. For access to non-NetWare drives, you must have one of the client engines, either the 51K version 5.10 WBTRCALL.DLL, or the version 6.15 WBTR32.EXE. I have a Visual Basic application using Btrieve, but I dont have access to any data dictionary (DDF) files. I guess the DDF information is embedded in the Visual Basic code, which I dont have access to. Is there any way to pull the data into Access? Good guess. And the answer is no. There is no practical way to pull data from Btrieve tables into Access without DDF files which define the Btrieve data. Probably the vast majority of Btrieve-based programs were written without DDF files. Up until a couple of years ago, most people developing Btrieve-based applications didnt even know what a DDF was. Btrieve stores and retrieves records as blocks of data based upon predefined indexes within the data, and does not concern itself with whats in the non-indexed portion of the records. Naturally, the application which files the data can be Vol. II, No. 4 October-December 1994 Btrieve Developer's Journal counted upon to understand how to interpret it. But in order to pull meaningful information from a data file, a generic database front end or report writer such as Access has to have a list telling it where the discreet pieces of information, or fields, are in the record. Thats essentially what a DDF is; a list, or actually, three related lists, FILE.DDF, FIELD.DDF, and INDEX.DDF, which tell Access what the files are in your data base, where and in what storage format the fields are within the records in those files, and what fields are indexed. The best place to get DDF files is from the application developer. The second best method is to get field layouts of the data files from the developer, and use them to create the DDF files yourself. The last resort method is to hack the data files by opening a file, looking at the raw data, and finding known values for fields within an individual record. Either of the first two methods is vastly preferable to the third. There are some Btrieve data files which simply cannot be defined using DDFs. If, for instance, the programmer stored some critical piece of information in a storage format which is not one of the standard DDF field types, that information will not be available to Access. The DDF standards were developed to define SQL data, and Btrieve data stored by non-SQL applications may not conform to the standard DDF definition rules. When I try to attach Access version 2.0 to one of my Btrieve version 6.x data files, I get Unexpected error from external database driver [7] Youre in luck, its just a bug. Your problem stems from a bug in the first release of the Microsoft Btrieve driver, BTRV200.DLL. Its been fixed. Theres a new one available on CompuServe in the MSACCESS forum library. The file name is BTR200.EXE, a self-extracting zip file containing everything you need to make the problem go away. Dont you wish they were all that simple? When I try to look at the records in one of my Btrieve tables, Access tells me it encountered an Unexpected error from external database driver [22] Your Btrieve file and your DDF definition for that file seem to have lost touch with one another, and its fortunate for you that youre still looking at Windows, and not at a black screen, a locked keyboard, and the perpetual flicker of a hard drive trying to find its boot sector. Access relies upon the DDF definition to tell it what to expect from Btrieve, and in this instance, the DDF lied. The error indicates that when Access asked for a record, Btrieve found a longer record in the file than the one Access requested. Check your DDF definition to make sure that all of the fields in the record are defined, and, if you have variable-length records in your data files, that the last field in your definition is a variable-length field type (either a NOTE or an LVAR type field) with a length sufficient to hold the longest record in the file. I get a GPF when I try to attach a Btrieve table in Access. Welcome to the wonderful world of modular software design. Your GPF means that somebody in the long chain of command between the disk drive and your application screen stepped on somebody elses memory address. Finding out who 11 Btrieve Developer's Journal did it is essentially a snipe hunt. The GPF message box will tell you in what module, and at what address, the error occurred. This is not necessarily meaningful information, as one module can set up the conditions which will percipitate a GPF in another module. But it's a place to start looking. A GPF in BTRV200.DLL or in MSAJT200.DLL usually indicate that the fault had something to do with Access, or with the DDF definition of the file, which is what Access uses to know what to expect from Btrieve. An error in WBTRCALL, or one of the other Btrieve components, usually indicates a problem with your Btrieve configuration. The weak link in this chain, if youre using NetWare Btrieve, is the DPMI layer between WBTRCALL.DLL and BREQUEST.EXE. Its critical that these two be matched correctly, or a GPF is a relative certainty. If youre not sure, you can download compatible versions of both in the file BTRREQ.EXE in the NOVLIB forum on CompuServe. Should the GPF persist, strip anything out of DOS that doesnt look as if it absolutely has to be there, and try again. If this cures the problem, you can begin carefully adding back device drivers and TSRs until the whole thing blows up again. If youre really, really lucky and the solar flares have died down, it might just keep working. But seriously, when this fails, the next most likely problem is that youve got an old piece of something loading in Windows where a new piece is supposed to fit, and the most likely culprit is Btrieve. Windows programs load modules called dynamic link libraries, or DLLs, which provide specific functions the programs need. Btrieve for Windows uses DLLs to hook into other programs. Windows hunts for dynamic link libraries first in the directory with the executable that wants them, then in the \windows\system directory, then it starts down the primrose PATH. And it loads the first match it finds. So now you must do likewise, and go rooting around through your \access directory, your \windows and \windows\system directories, and all the directories in your path (dont forget network directories, especially the NetWare \public directory), looking for outmoded Btrieve DLLs. Delete them, rename them, but one way or the other, get them out of harms way. I installed the Btrieve for Windows drivers, found a set of DDF files, and tried to open FILE.DDF. Now I get Invalid entries in [Btrieve] section in WIN.INI What did I miss? Perhaps the most frequent and least informative of the Microsoft Access/Btrieve error messages, this one sends you looking for a section in WIN.INI which may not even exist, and gives you no indication of what you need to do when you get there. The Btrieve Client Engine reads its initialization parameters from WIN.INI or BTI.INI, depending upon which version of Btrieve youre using. The NetWare Btrieve NLM reads its configuration options from the server BSTART.NCF file, configured using BSETUP. But Access requires the [btrieve] section in WIN.INI regardless, with an options= initialization string. The file BTRIEVE.TXT in your \access directory explains the recommended and required settings for these options. The recommended options line looks like this: options=/m:64 /p:4096 /b:16 /f:20 /l:40 /n:12 /t:c:\btrieve.trn If you're using the local Btrieve version 5.10W DLL, this options line in WIN.INI will initialize Btrieve correctly. If Vol. II, No. 4 October-December 1994 (800) 828-7438 or (615) 386-3100 FAX: (615) 386- you're not using this driver, however, the options that Access checks and the options you end up using with Btrieve may not be the same options, and this can lead to aberant behavior in Access. The most important consideration is that Btrieve transaction precessing be enabled. Access uses transaction processing for its own purposes, one of which is apparently to protect the DDF files from the possibility of destructive reads. If you're using the Btrieve Client Engine version 6.15, you'll need to place the correct options in the BTI.INI file in your \windows directory. Note that with the 6.15 engine, the meaning of the /t parameter has changed. You will now use the /t parameter to specify the maximum number of transactions, and this number must be greater than zero (15 is the default). The transaction file name is always BTRIEVE.TRN, but you will need to specify a directory location for the transaction file on the trnfile= line below the options= line. Disregard what the Access BTRIEVE.TXT file says about where to put transaction files. In a multi-user, non-clientserver environment, each Btrieve Client Engine requires its own transaction control file, so make sure that this file is in its own directory for each installation of the client engine. If you're using NetWare Btrieve NLM, these options are set in the BSTART.NCF file on the server, using the BSETUP program. The NLM always uses the transaction control file BTRIEVE.TRN in the NetWare system directory, but you must specify a maximum number of open transactions greater than zero. Other parameters can cause problems as well. For instance, if your Btrieve configuration lacks a /u parameter, and you have data in Btrieve files which use Btrieve data compression, you wont get the Invalid options message, but you will get Unexpected error from external database driver [58] when you try to read a compressed record. Finally, this error is prone to appear quite suddenly in an application that used to work. It usually manifests itself right after youve installed some other piece of software that uses Btrieve. Its smart to check your [btrieve] options line after installing anything Btrieve-related, to make sure the installation hasnt shot your hard-won Access parameters in the foot. Access opened my DDF, but I still dont see any tables in it. Either there are no tables in your DDF, or transaction processing is not enabled. If youre running the Btrieve NLM, chances are that Btrieve transaction processing is disabled at the NetWare server. Youll need to LOAD BSETUP, the NetWare Btrieve setup utility, either at the NetWare server console, or at a workstation running the RCONSOLE utility. Use this setup program to increase the Number of Transactions parameter. This parameter sets the maximum number of clients which may have transactions open on the server at any given time. The default value for this parameter is 15, but must be greater than zero in order for Access to attach to server-based Btrieve files. When I use Access to try to attach my Btrieve version 6.x tables, I get the error message: Disk or Network Error. Youre trying to open a Btrieve version 6.x file with a Btrieve for Windows version 5.x driver. Btrieve returns a status code of 2, which Access interprets and reports as a disk or (800) 828-7438 or (615) 386-3100 FAX: (615) 386-3135 network error. In order to open a Btrieve version 6.x file, you must have a Btrieve for Windows version 6.x engine. You wont be able to open a Btrieve version 6.x file on a local hard disk without the Btrieve for Windows version 6.15 Client Engine, and in order to open a version 6.x file on a NetWare server, youll need to be running version 6 of the Btrieve NLM, and attaching to the file using the client/server Btrieve for Windows DLLs and BREQUEST.EXE. Btrieve version 6.x, on the other hand, will read and write Btrieve version 5.x format files. Can Access work with Btrieve files through the Btrieve VAP? Yes. If youre using a version of NetWare Btrieve implemented as a VAP, Access will attach to this data. Set up Btrieve in exactly the same way you would when using the NLM version of NetWare Btrieve, with BREQUEST.EXE running underneath Windows and the NetWare requester DPMI library WBTRCALL.DLL, and Access will never know it isnt dealing with the NLM. When I export a table to Btrieve file, Access creates an additional primary index field called M_I_C_R_O_S_O_F_T even when I have a primary key defined in the Access table. Is there a way to disable creation of this 4-byte index field? This field is created whenever Access has to create a DDF definition for the file. The field is necessary because of some assumptions that Access has to make about the data. First it initializes enough records to hold the data, and then attaches to it and modifies the fields. If you attach to a table in a DDF file that has already been defined and simply modify the data that it refers to, Access will not create this field. I finally got Access to attach my Btrieve files. But some queries are unbelievably slow. Whats going on? Access is a relational database front-end, which is built upon and which enforces the constraints of a database language called SQL. Because Btrieve does not enforce SQL relational database structure on its data unless the data was created using Scalable SQL, Access is limited in the assumptions it can make about the file structure. It's safest to make no assumptions, and for any given SQL query, to perform a complete file scan, matching the records returned with the query criteria. Not only is this the safest approach, its also the slowest. The native Access driver for Btrieve seems to be willing to make use of indexes to optimize its queries, but it will not use manual or null indexes, indexes which employ an alternate collating sequence, or indexes which have any segments which do not correspond to complete fields. And, naturally, any query which selects records based on fields which are not indexed will require a complete file scan. Access 1.0 documentation seemed to imply that segmented indexes on non-contiguous fields were not supported, either, though this may not be true of Access 2.0. The way in which Access interprets a query will also affect performance. Though SQL dictates the query syntax, it does not stipulate how a query is to be implemented by the database engine. The only control the user has over Access, in terms of how records are to be retrieved, is at the SQL level with the definition of the query. ² Vol. II, No. 4 October-December 1994 Btrieve Developer's Journal BTRIEVE TECHNOLOGIES TECHNICAL CORNER OCTOBER-DECEMBER, 1994 SUPPLEMENT TO B TRIEVE DEVELOPER'S JOURNAL MAD'S COLUMN Hello and welcome to the fall issue of Btrieve Technologies Tech-Corner. It was exciting and interesting to see and meet with everyone at THE SUMMIT. It had been awhile since I had the opportunity to meet with many of you. And I appreciate the time that everyone took out of their excessively busy schedules to meet with us. We received a lot of information from you directly on what product features (support for greater than 4GB files, nested transactions), utilities (more complex and user friendly), and drivers (native ODBC) you need to maintain your competitive edge. The exposure of our Microkernel Database architecture helped many of you understand BTIs positioning in the dynamic world of databases. It was good to hear, as several of you left the Q&A Session on Tuesday, that you are now confident that Btrieve Technologies is alive, creating new products, adding key new features and looking towards the future. One request: Ive placed on CompuServe a purposefully short survey with features that you would be willing to pay for in a billable support program. We are currently amassing that information to create programs that fit our customers needs. If you were unable to attend The Summit, Id appreciate your response. We have not formally defined any programs yet and await your input. We hope to have these programs in place by early to midyear 1995. Wishing you a Happy, Healthy and Terrific start of the new year. Happy Programming!! Mad Poarch Vice President, Customer Service Btrieve Technologies, Inc. TECHNICAL Q&A - BTRIEVE V6 OPTIMIZATION What are the issues involved in fine tuning a Microkernel NLM? To fine tune the Microkernel engine, both the hardware and the NLM configuration should be examined. It is recommended that any Database Server be at least a 486 66/MHZ machine and that it be dedicated to providing database services. The Microkernel NLM configuration options can affect performance. Unfortunately, it is difficult to make a blanket statement that will guarantee improved or optimal performance. In the answers to each of the questions below, we have tried to cover common aspects of how performance can be affected by the NLM configuration, as well as other platform considerations. Can page size affect the way the Microkernel performs? When choosing a page size for a file there are issues involved that can affect performance. Using a page size that is an even increment of 512 (1024, 2048, 3072, 4096) is suggested. In the NetWare environment, blocks are usually read in even increments of 512. If you specify a page size other than those listed here, NetWare may read two blocks for a single page read. There are at least 3 ways in which to determine page size. The first is to utilize disk space, to put as many records on the page with the least amount of wasted space. The second is to put only one record on a page. The third is to place as many records on a page as possible. All three scenarios have their pros and cons, and depending upon the usage of the system can affect performance. When multiple records are on a page, chances increase as the file is used that the Microkernel engine will be (800) 828-7438 or (615) 386-3100 FAX: (615) 386-3135 holding the page requested in cache, thereby reducing the number of disk hits necessary to read records. However, if the data set being read is very select and predictable, then the Microkernel engine may be managing pages that will never be fully used. In that case, the fewer records per page the better. Having fewer records per page is also useful when using Concurrent Transactions. Page locks are used to determine concurrency in a Concurrent Transaction. Fewer records on a page reduces the amount of page lock contention that may occur in this type of transaction. I am trying to perform transactions in the NetWare environment. What settings do I need, and should the files be flagged Transactional? In order to perform transactions (Concurrent or Exclusive), the Microkernel Engine will have to be configured to support transactions. The Number of Transactions value will need to be set. For the NLM this is typically set to the same value as the Number of Remote Sessions. When a Microkernel Transaction is initiated from an application, any server that the workstation is attached to AND which has the Microkernel engine loaded on it, MUST be configured for transactions. Flagging the file Transactional will not invoke TTS. The Microkernel Engine IN THIS ISSUE Technical Q&A: Btrieve Optimization...17 The Future of the Microkernel................19 Technical Insights..................................22 Vol. II, No. 4 October-December 1994 Btrieve Developer's Journal (NLM) uses the flag to indicate that all operations should be treated as single system transactions. The Microkernel Engine has an internal system transaction. A system transaction can be composed of several Microkernel operations. When the system transaction is synched all the operations are committed to the operating system. The TTS flag tells the Microkernel engine to treat a single operation on the file as a system transaction. Flagging files as transactional will cause performance to decrease because of the inefficiency of treating each operation as a system transaction. The trade off is tighter data integrity. For the workstation products (DOS and Windows) there is an /e option that provides transaction durability. When the application receives a status of 0 on operation 20 (End Transaction) and the /e option is in use, this means that the system transaction has synched and the transaction is committed to the operating system. Accelerated mode in the 5.x engines allowed for quick cache access to files. Does 6.15 have the same capability? Accelerated mode implies that the integrity of the file is not essential to the state of the system, and that the file will be accessed in the quickest way possible. In the 5.x engine this was done by terminating pre-imaging and relying on caching for Microkernel operations. With the 6.15 engine and 6.x files, pre-imaging is no longer used and system transactions provide for caching of operations. In essence, accelerated mode and normal mode are one and the same, without the implication that data integrity is a low priority. If it makes sense to open the file in accelerated mode, developers should continue to use the setting. In the future accelerated mode may reappear. Why does the conventional memory footprint for Btrieve for DOS 6.15 vary depending upon the memory manager? The footprint can vary because of the protected mode stub that is loaded with Btrieve. Depending on how a memory manager is configured, the stub will have to make different real mode memory allowances. 14 Btrieve Developer's Journal Btrieve Technologies technical support staff has a 3 page white paper on different configurations and memory consumption results. Because real mode memory consumption is such an important issue, Btrieve Technologies has taken a hard look at how much memory the Microkernel engine is using during the load process and once it is resident. Btrieve Technologies has a Btrieve for DOS update that is available to all registered users. We have been able to trim conventional memory consumption by about 20K in some instances. The 5.x engines had a maximum cache size of 64K. Why do the new engines have a default size of 512K? The new engines require more cache due to the nature of how the Microkernel Engines background writer works. In essence, the new engine relies heavily on pages being present in cache to cut down on disk accesses. For both the DOS and Windows engines, the cache is allocated in upper memory areas. That is why the system requirement for RAM has been expanded. The use of a larger cache provides for faster performance and more efficient use of memory. Allocating too small of a cache for the Microkernel engine can affect its performance in any environment. The optimal setting is to minimize disk hits and maximize cache hits. Once a page is read by the Microkernel engine, the optimal configuration would be to never have the engine reread the page. Default settings for this parameter are generally sufficient. However, if there is memory flexibility in your system, give the engine more cache. Giving the Microkernel engine too much memory will not degrade performance. Which Microkernel parameters affect performance? See the table at the top of the page opposite, outlining parameters that do not directly affect performance and those that do. Options marked with an asterisk (*) are documented in the online help files that come with the 6.15 version of the Microkernel engine. WHOS WHO AT BTRIEVE TECHNOLOGIES Doris Eldridge Acting Director of Development Doris primary responsibilities include coordinating the releases of all of Btrieve Technologies software products. She works with developers, QA engineers, and technical writers to define schedules, resolve technical issues, and set priorities. Other responsibilities include supporting beta sites, reviewing documentation, and assisting in testing software. As acting head of development, Doris also interacts with other departments such as marketing, sales, and services to coordinate project work, and also handles the administrative issues for the department. Vol. II, No. 4 October-December 1994 Doris joined Btrieve Technologies, Inc. as a founding team member in April of 1994. Prior to that, she worked as a software engineer at SoftCraft, Inc. for approximately six months, shortly before the company was acquired by Novell, Inc. She worked in the Database Products development group for Novell, first as a software engineer, and then engineering lead for the NetWare SQL product, from the time of the acquisition until the group was sold to Btrieve Technologies, Inc. In August, 1993, she assumed responsibility for the Quality Assurance group for the Austin division of Novell. Away from the office, Doris, her husband, Larry, and their two girls, Jennifer, 14, and Nicole, 9, enjoy spending time at their weekend place in the country, a short hours drive from Austin. Favorite vacation spots include South Padre Island, Texas and Estes Park, Colorado. Doris also enjoys playing softball in a recreational softball league with her coworkers and friends. (800) 828-7438 or (615) 386-3100 FAX: (615) 386- Why is Btrieve for DOS 6.15 slower than Btrieve for DOS 5.10a? Before the release of Btrieve for DOS 6.15, several of our beta customers reported the improved performance of inserts, updates, and deletes. We were all concerned when customers reported decreased performance of reads with the released product. Through customer test cases and development efforts we have been able to improve the Btrieve for DOS 6.15 engines performance. Engineering was able to identify a performance degradation when switching from real to protected mode. Changes have been made to eliminate the degradation. These engineering changes are in the Btrieve for DOS 6.15.1 update. Users that were registered by October 24th, 1994 will receive the update in the US mail. The update has been made available on CompuServe in the BTRIEVE forum. The forum has special instructions for obtaining the update. How can the system be monitored to insure that it is configured properly? The Microkernel Engine returns appropriate status codes for configuration problems. For instance, if there are not enough file handles configured, then applications will receive a status of 87. If there is not enough memory specified by the cache allocation parameter, a status 100 will be returned. Most Btrieve status codes provide specific information regarding what has occurred to create a non-zero status code. All server versions of the Microkernel Engine will provide a monitoring utility. In the NetWare environment this utility is BTRMON DO NOT AFFECT PERFORMANCE DO AFFECT PERFORMANCE Number of Open Files Number of Handles Number of Locks Number of Transactions Largest Compressed Record Size Largest Page Size Number of Remote Sessions Cache Allocation Perform Index Balancing Logging of Selected Files Create Files in Pre-v6 Format Create Files as Transactional (NLM) Transaction Durability * Transaction Bundling * NLM. System configuration can be monitored and resource usage can be verified through the monitoring facilities. If there are two applications that require the Microkernel Engine, what settings should be used? It is always possible that two applications that require the Microkernel Engine require different settings. For example, some applications may require transactions while others do not, or some may require an extensive number of file handles. The best rule of thumb is to adjust to the highest settings, and leave settings alone that enable specific functionality. For instance, if compression is set, leave it set. If your application does not require compression it will have no affect on your application, however by changing it another application may break. Again, if a configuration is set improperly, the application will receive an appropriate status code indicating the problem. Typically, I use BUTIL.EXE to create my files. Every time I try to create my files with BUTIL 6.15 I receive a status code of 97. What is causing the 97? The status 97 indicates that BREQUEST needs a larger /d parameter and that the Microkernel Engine also needs to be configured with a matching value. In this case BUTIL version 6.15 is setting the data buffer length to 33K. Consequently, the Microkernel Engine (NLM) and the /d for BREQUEST need to be set to 35000. The other alternative is to continue using BUTIL version 5.12. What is the TIMER value in the BTI.CFG file? Btrieve for DOS version 6.15 is architected to include a foreground and a background task. In a single tasking OS, such as DOS, task switching is not available, but it can be simulated. The Microkernel engine for DOS accomplishes this by hooking into the timer interrupt to simulate task switching. In some configurations, other applications may also use the timer interrupt. If these applications are not wellbehaved, the system may hang when multiple applications attempt to interface with the timer interrupt. The timer entry is used to disable Btrieves use of the DOS timer interrupt. By default, this entry should always be set to Yes. You may need to disable the timer if you experience system hangs or abends while running your Btrieve applications. FUTURE OF THE MICROKERNEL EVOLUTION OF THE MICROKERNEL DATABASE ENGINE Since its introduction in 1982, Btrieve database technology is now in its sixth generation. Changes over the years have included increased functionality, network support, clientserver capability, and support for an ever increasing number of platforms and languages. Three central philosophies have driven the technology development of these products: Make efficient use of hardware and operating system resources, maintain the integrity of data, and maintain a consistent interface. The fact that Btrieve was originally designed for the PC gives it a (800) 828-7438 or (615) 386-3100 FAX: (615) 386-3135 great technological advantage over systems which have been scaled down and adapted from mainframe and microcomputer implementations to run on stand-alone and network systems. This can be seen in a quick comparison of the sizes and relative speeds of other database engines. Btrieve has long been recognized for its performance, but Vol. II, No. 4 October-December 1994 Btrieve Developer's Journal DATA MODEL DEPENDENT ACCESS MODULE FUNCTIONS Logical functions Schema (row, column, table...) Definitional functions Operations (join...) Btrieve Navigational Model Scalable SQL Relational Model Object Database Model Custom Data Models DATA MODEL INDEPENDENT CORE ENGINE FUNCTIONS Physical data access Advanced caching Data integrity enforcement Transaction processing MICROKERNEL DATABASE ENGINE Microkernel Database Engine Architecture more importantly for its integrity, as is evident by the fact that seven of the ten leading accounting system vendors are built on the Btrieve database engine. And as Btrieve has added features over the years, the API has remained remarkably consistent. So consistent, in fact, that applications written for Btrieve version 1 will still run on top of Btrieve version 6 without modification. And this consistency is also enforced across platforms, allowing an application to run on a single computer, or in a client/server environment on a Novell network, without any modification. MICROKERNAL ARCHITECTURE The release of Btrieve version 6 marks the introduction of the Microkernel architecture, a new architectural model for the Btrieve database products. The DOS and Windows Btrieve engines have been completely re-coded from a common C/ C++ code base derived from the NetWare Btrieve NLM. This code will form the basis of the platformindependent Microkernel Database Engine. The Microkernel will handle all of the core database functions, Btrieve version 6.5 16 Btrieve Developer's Journal Vol. II, No. 4 October-December 1994 including physical data access, advanced caching, transaction processing, and data integrity enforcement; functions which are common to all data models. One of the benefits of this Microkernel architecture is that it allows concurrent multiple data model access to the same data. Because the Microkernel limits itself to core database functions, the design is entirely datamodel independent. Currently Btrieve Technologies has two data model implementations which use the Microkernel to provide core services: the Btrieve navigational model interface, and the Scalable SQL relational model interface. Because data integrity is enforced at the core level, both of these data access models can be run simultaneously against the same physical data. This architecture also leaves the door open to new database models such as an object model interface and tools to develop custom database models. Functionality can be added to the Microkernel to support these models as they evolve, supporting new types of applications and information collaboration. This design will also improve performance for existing applications, which will benefit from new caching and multi-threaded processing performed by the (800) 828-7438 or (615) 386-3100 FAX: (615) 386- allocation table (PAT) and index pages. BTRIEVE NAVIGATIONAL MODEL INTERFACE Scalable SQL version 4 Microkernel. And it will be fully compatible with existing applications, once again because the basic interface will remain consistent, though new features will be added. And finally, because of the common C/C++ code base, this architecture will be easily ported to other platforms. BTI already has it in place in NetWare, Windows, and DOS, Windows NT and OS/2 are both in pre-release. MICROKERNEL DATABASE E NGINE FEATURES In the current release, the Microkernel includes features to support record set operations, otherwise referred to as extended operations. This includes the capability to do partial record retrieval and record filtering. Huge record support is implemented at this level as well through chunk operations, effectively removing any limits to individual record size. Percentage operations, which indicate how far you are along a given index path are also supported in the current release, and they are useful not only in GUI applications for determining thumb scroll positioning, but they are also one of the tools which will enable true costbased optimization in future releases of Scalable SQL. The current Microkernel engine enforces data integrity constraints. If your database is defined using Scalable SQL to enforce relational integrity, that is enforced at the Microkernel level, so that an application accessing that data using another database model such as the Btrieve navigational model will not be able to violate the relational integrity of the data. The Microkernel is a true multi-threaded engine which performs all of its disk IO in the background. A complete transaction/isolation manager eliminates the possibility of dirty reads. Performance is enhanced by more efficient internal algorithms, more efficient caching, and the addition of symmetric multiprocessing support. Planned Microkernel features include transparent two-phase commit, support for nested transactions which will be based on the currently implemented concurrent transaction support, capacity for files larger than 4GB, improved continuous operation support which is not dependent upon sparse files, eliminating the potential for file corruption in the event of a system failure during continuous operation and allowing cross-platform support for continuous operation on platforms which do not implement sparse files. Future versions of the Microkernel will support specialized data and key types, particularly array keys, message/full-text indexing, and object store. A scripting language for stored procedures and event triggers will be implemented at the Microkernel level, and core data management functions will also include support for database replication and versioning. Versioning will allow the Microkernel to maintain a database in a static state based upon the assignment of a version, while still allowing updates to the files which will not affect the versioned data. Planned performance enhancements for the next version include IPX requesters, persistent caching across file opens and closes, and a consolidated log file. Future version releases will implement readahead caching, including a requester cache, self-tuning parameters, and cache weighting , especially of page (800) 828-7438 or (615) 386-3100 FAX: (615) 386-3135 Btrieve version 6 is shipping currently as an NLM, and as a client engine in Windows and extended DOS. Versions for OS/2 and Windows NT are currently in pre-release. Btrieve 6.5, scheduled to begin shipping during the second quarter of the coming year, will feature triggers and stored procedures, improved performance, support for nested transactions, support for huge files, and transparent two-phase commit. Enhanced log capabilities will include single, durable log file maintained by a separate thread, providing better performance. The Windows and Windows NT drivers will feature a DLLonly requester. SCALABLE SQL RELATIONAL MODEL INTERFACE Relational APIs will include the native Scalable SQL API and ODBC. ODBC support is currently provided by Microsoft and Q+E\Intersolv. BTI is currently considering whether or not to provide direct ODBC support. SQL syntax in future versions will continue to support Scalable SQL v3.x syntax. Future versions will add compliance with the at least level 1 of the SQL 92 standard, and will add support for SQL3 level syntax with triggers, assertions, control statements, and selected other syntax additions. Scalable SQL 3 is currently shipping as an NLM, and as a Windows client engine. The extended DOS client engine is currently in beta. Scalable SQL 4 is slated to begin shipping in the coming year. New features will include full cost-based optimization using the Microkernel percentage operations in its cost analysis algorithms. It will also add support for SQL3 level syntax, and will include a scripting language for implementing event triggers and stored procedures at the Microkernel level. Plans are to add platform support on OS/2 and Windows NT with the version 4 release. Vol. II, No. 4 October-December 1994 Btrieve Developer's Journal TECHNICAL INSIGHTS Btrieve for DOS v6.15.1 Update Below is a description of the critical problems that are fixed in the Btrieve for DOS v6.15.1 product update, which began shipping to registered owners of Btrieve for DOS v6.15 Developers Kit and Client Engine in November. If an error is returned on a Btrieve INSERT, UPDATE or DELETE operation and the application then continues to insert records without closing the file, the size of the Btrieve file can become very large. Under some conditions, the performance of the read operations in Btrieve for DOS v6.15 is worse than with Btrieve for DOS v5.10a. If a Btrieve file has an owner name with encryption enabled, performing a massive insert will cause unexpected errors or the machine may lockup. You can now access Btrieve files that are located on CD-ROMs. Previously, status 12 was returned when you attempted to access a file on a CD-ROM drive. When the first workstation issued a GET FIRST with a 200 bias, it did not release the lock following an update operation. You can now specify the location of the Btrieve transaction file (BTRIEVE.TRN) on the command line using the /t option. The format for the /t option is as follows: /t:[number of transactions]:[transaction file] You can specify either the number of transactions, or the transaction file name, or both. If both are specified, then the number of transactions must be specified first. If either value is omitted on the command line, then the value in the configuration file (BTI.CFG) applies. If your application does not use transactions and you want to disable the Microkernel from opening the transaction file, you can specify the following: /t:0:nul Earlier versions of Btrieve v6.x removed the ability to create a segmented index that overlapped with an AUTOINC key. This was available in Btrieve v5.x. It has been restored with this patch update. Btrieve allows the segmented key to overlap the AUTOINC key only if the key number of the AUTOINC key is less than the key number of the segmented key. You can now load Btrieve for DOS in high memory, reducing the conventional memory footprint size. Some conventional memory will still be used for the DOS/4G interface. The amount of memory used depends on the memory manager configuration that you have installed. Also the amount of memory available for the largest executable program is increased by about 20K bytes, as a result of better memory management by the Microkernel loader. You may still experience problems when 18 Btrieve Developer's Journal attempting to unload Btrieve, if it is loaded in high memory. This could be due to the combinations of other programs that are also loaded high. If you experience such a problem, you will not be able to load Btrieve in high memory. Under some conditions, executing a BUTIL STOP command caused the workstation to hang. This problem has been fixed. Scalable SQL Generates Microkernel Status 21 Status 62 on Update Chunk Btrieve 6.1x Scalable SQL for Windows 3.01 When using the local Scalable SQL for Windows engine and the Client/Server Microkernel engine, a status 21 Key Buffer Parameter is Too Short will be returned for any query that requires a temporary sort file to be built. This error does not occur when using the Client/Server Scalable SQL engine, or the local Scalable SQL for Windows engine with the local Microkernel engine. If the Microkernel configuration specifies both local and server access, and the Scalable SQL temporary sort file directory is specified as a directory on the local drive, queries that require temporary sort files can be run against the local Scalable SQL engine. With this configuration, all files located on the server will be handled by the requester, and temporary sort files will be built on the local drive by the local Microkernel engine. This configuration may provide performance improvements since the data being transferred to and from the temporary sort file will not have to be re-transferred over the network. However, this configuration does require that the workstation have sufficient memory for the local and requester Microkernel components along with the Scalable SQL local engine. The workstation must also have sufficient disk space to store the temporary sort files. The size of these files will depend on the amount of data satisfying the query. BREQUEST.EXE Memory Usage NetWare Btrieve 6.1x The amount of conventional memory used by Brequest v6.1x varies slightly depending on the version, and the directory from where it was loaded. However, the latest version of Brequest, v6.16, takes 384 bytes less memory than Brequest v6.10e. For example, loading Brequest with default parameters from the C:\ directory produces the following results: 6.10e 34320 bytes 6.15 33488 bytes 6.16 33936 bytes Loading from different directories may produce slightly different results - longer paths will Vol. II, No. 4 October-December 1994 increase the memory usage by a multiple of 16 bytes. For example, loading from the network directory AUS-TIN\BRO:W\LANDERSO\DOCS produces the following results (an additional 32 bytes for each version): 6.10e 34352 bytes 6.15 33520 bytes 6.16 33968 bytes The increased memory usage due to the longer path is caused by the allocation of a copy of the environment plus the programs filespec by DOS when the TSR loads, and not something specifically allocated by Brequest.exe. A status 62 (incorrect descriptor) can incorrectly be returned on an Update Chunk operation, specifically a RANDOM, INDIRECT operation. This occurs in the Btrieve for Windows engine 6.15.1 and the Btrieve for Windows requester 6.15.1. The problem occurs because Btrieve is verifying that the structure used to describe the operation does not lie in the memory area that is holding the data that will be used to update the data. So the descriptor would look like: Descriptor.dwSubFunction = INDIRECT_RANDOM_CHUNK_SUBFN; Descriptor.dwNumChunks = 1L; Descriptor.dwChunkOffset =15; Descriptor.dwChunkLen = 0x1000; Descriptor.lpChunkData = lpMemBuf; wDataBufLen = sizeof(Descriptor); When Btrieve gets the call, it has the address of Descriptor, being 241F:0234 for example. Then it looks at the value in Descriptor.lpChunkData, being 1F49:0000 for example. It then takes the length specified by Descriptor.dwChunkLen and adds it to the address of Descriptor.lpChunkData, so 0x1F49 + 0x1000 = 2F49. Because 2F49 falls below the Descriptor address Btrieve assumes that the actual Descriptor is in the memory area that will be used to update the file, thereby causing a 62. However, because this is the Windows environment, the two pointers specified by Descriptor and Descriptor.lpChunkData are not related so using pointer arithmatic as described above does not work. The pointer values are selectors, therefore if the two pointers do not have the same selector value (241F for Descriptor and 1F49 for lpChunkData) they are not in the same memory area. The usage above would apply if they were segments. The solution is to allocate the descriptor with the data segment: hMemBuf=GlobalAlloc(GMEM_MOVEABLE, (DWORD) (BUFFER_LEN + Sizeof(Descriptor) + sizeof(TEST_RECORD)); lpMemBuf=(LPBYTE)GlobalLock(hMemBuf)); (800) 828-7438 or (615) 386-3100 FAX: (615) 386- Btrieve File Corruption Btrieve for DOS 5.10a When investigating a case of Btrieve file corruption, there are four general causes. More than 90% of all Btrieve file corruption cases are caused be problems in categories III and IV. I. File corruption is being caused by a problem with the Btrieve engine. If this is the case, the corruption should be reproducible. To isolate Btrieve as the cause, you must provide Developer Support with a test case that demonstrates the problem. This test case can be either your application, or a test application based on the code in your normal application. Btrieve cannot be identified as the cause without a test case. Btrieve logging and the Rollforward utility can also be utilized when trying to produce a test case. Similarly, in the Btrieve 6.x NLM environment, the BRECORD utility can be used. Always make sure you are running the latest version of Btrieve with any available patches applied. Patches can be downloaded from CompuServe, or you can contact Developer Support and request that the patches be mailed to you on diskette. If Btrieve is found to cause the file corruption, the problem will only be fixed in the current or next version of Btrieve. Development will not fix older versions that are no longer shipping. II. File corruption is being caused by the application. If the application can make Btrieve calls successfully, but data returned by Btrieve is corrupted, or if the workstation hangs, the cause can usually be found in the application. Common causes include overwritten data buffers, position blocks or memory in general. Utilities such as POSCHECK can help track down some of these errors. Various Btrieve debugging utilities are available for download from Compuserve, or you can contact Developer Support and request that the utilities be mailed to you on diskette. III. File corruption is being caused by hardware incompatibility or malfunction. Check all the workstation and server hardware. Hardwarerelated causes can be difficult to isolate, and sometimes may require you to swap components. If the cause can be proven to stem from one particular workstation, it is usually hardware related. When running a NetWare LAN, always make sure server hardware, workstations, LAN cards and any other components are NetWare-certified. IV. File corruption is resulting from interaction with another software component, including other TSRs, memory managers or device drivers at the workstation, as well as LAN card drivers and other NLMs at the server. Remove all unnecessary components and see if the problem persists. If not, add the components back in one at a time to see which one may be causing the conflict. Also, make sure that each component is the current version and is NetWare-certified for the NetWare version running on the server. The best approach to take when investigating Btrieve file corruption is isolate and reproduce. Always make sure you start your tests with clean files by rebuilding any files that produced an error during your investigation. Universal Naming Convention (UNC) and BREQUEST BREQUEST 6.10e, 6.15, 6.16 UNC is not supported with BREQUEST.EXE. A status 12 (file not found) will be returned if the Universal Naming Convention (UNC) is used to qualify a file path on a Btrieve OPEN operation when using BREQUEST.EXE. For example, an OPEN request for the file \\AUSTIN\BRO\OS2\LHEATER\TEST\PATAPP.DTA will return a status of 12. Do not use the Univeral Naming Convention (UNC) to specify SERVER/VOLUME with BREQUEST.EXE. If Server/Volume must be specified, then SERVER/VOL:\path is the correct way to specify the name of the path. This is considered to be NetWares convention for file specification. Opening Files on a CD-ROM Drive Btrieve for DOS v6.15.1 Btrieve for DOS v6.15.1 will let you open a Btrieve file on the local CD-ROM. However, there are some issues to be aware of: A CD-ROM drive is handled as a network drive. The default file sharing mode on a network drive is MEFS (multi-engine file sharing). Since the CDROM is a read-only device, Btrieve cannot create the lock file when it tries to open the Btrieve file. Status 81 (lock error) is returned in this situation. You can avoid this error in the following ways: 1. Open the file with the SEFS (single-engine file sharing) bias. 2. Specify SEFS for remote files in BTI.CFG file. 3. If MEFS is specified, redirect the lock file using the /i option to a different drive. Loading BREQUEST.EXE High NetWare Btrieve NLM 6.10 When BREQUEST.EXE v6.10x is loaded into memory, the transient portion of the TSR requires a maximum of 173KB. The only memory areas below one MB with enough space to accommodate this driver are the conventional memory area and the Upper Memory Block (UMB). Therefore, when BREQUEST.EXE is loaded high, it will be placed in the UMB if space is available. After the TSR has loaded, the resident portion occupies 34KB. BREQUEST.EXE can only be loaded high if the IPX (IPX.COM or IPXODI.COM) driver has been loaded first. NETX can be loaded either before or after Brequest is loaded. If an attempt is made to load BREQUEST.EXE high after IPX and NETX have been loaded high, the system may either hang or return an 80386 Processor Exception error if there is not enough available memory. BREQUEST.EXE can also be loaded in base memory with the drivers loaded high. (800) 828-7438 or (615) 386-3100 FAX: (615) 386-3135 Scalable SQL Programmers Manual Documentation Error Scalable SQL for Windows 3.01 There is a reference to the Getting Started manual in the Scalable SQL for Windows Programmers manual in the last paragraph on p4-28. This should refer to Chapter 3 (Query Optimization) in the Scalable SQL Reference Manual. Redirecting Pre-Image and LCK Files on NetWare Btrieve for DOS In a single-volume NetWare environment, Btrieve pre-image files for 5.x format files, and LCK files used by Btrieve v6.15 in MEFS (MultiEngine File Sharing) mode can be redirected to a map root drive to avoid giving users CREATE rights in the directory containing the Btrieve data files. When using a client version of Btrieve (Btrieve for DOS, OS/2 or Windows) in a NetWare environment, administrators may want to configure NetWare so that users have rights to read and write to the directory containing the Btrieve data files, but not create new files in that directory. However, without Create rights, Btrieve cannot access the data files, since it cannot create the pre-image files used when accessing Btrieve files in the 5.x format, or the lock file needed for MEFS. By default, Btrieve creates the pre-image files in the same directory as the Btrieve data files. Btrieve can be configured to redirect the preimage and lock files to a different drive with the / i: option, for example: Btrieve /m:38 /p:4096 /e /i:G This configuration tells Btrieve for DOS to create the pre-image and lock files on drive G (whatever that might be mapped to). Drive G must have the same directory structure as the drive with the Btrieve files. For example, if the Btrieve file FILE1.BTR is in the directory F:\APPL\DATA, the pre-image file FILE1.PRE will be created in the directory G:\APPL\DATA. Since all users must share the same pre-image files, everyone must use the same redirection path and a local drive cannot be used. One solution is to set up the matching directory structure on a different volume, and map the G: drive to that volume. In an environment where the server only has one volume, the only way to set up a separate directory for pre-imaging where users will have Create rights is to use the MAP ROOT command. For example, if the Btrieve data files are in the directory F:\APPL\DATA, another directory can be set up like \PRE\APPL\DATA where users are given Create rights. Then, issuing the command: MAP ROOT G:=\PRE will set up a map root drive that can be used in the Btrieve command shown above. The pre-image files will be successfully redirected to the \PRE\APPL\DATA directory instead of the \APPL\DATA directory. Vol. II, No. 4 October-December 1994 Btrieve Developer's Journal Set Directory Operation Will Not Cross Drives NetWare Btrieve NLM 6.10 The Btrieve Set Directory (17) operation does not change the directory if a path on a different drive is specified. For example, if the current working directory is F:\APPL, and a null-terminated KeyBuffer of G:\DATA is passed to the SetDirectory operation, a status 0 is returned but the directory is not changed. This result occurs even if F: and G: are mapped to the same server and volume. Subsequent attempts to open a file that is located in G:\DATA returns a status 12 (File Not Found). If the Set Directory operation is given a path that is on the same drive as the current working directory, such as F:\BTRDATA, it works correctly. This problem exists with BTRIEVE.NLM v6.10c, and all 5.10x versions of client-based Btrieve for DOS, OS/2 and Windows. If the Btrieve files to be accessed reside on a different drive than the current working directory, the drive and path along with the file name can be specified in the Open operation instead of using the Set Directory operation. The problem does NOT exist in the v6.15 Btrieve for Windows client. Scalable SQL for Windows Registration Scalable SQL for Windows 3.01 If someone purchases both a Single-User copy and the Unlimited License copy of Scalable SQL, and attempts to install them in the same place (such as C:\BTI), the registration program will not run for the second installation. The files installed by these two products are identical; the products only differ by the license. The single-user engine is not crippled in any way. So, the double installation wont cause you to lose any files, but the registration program thinks its already been run, and does not run again. To complete the registration for the product being installed second, just re-install it in a different directory so that the registration program will run. Phantom Users in BTRMON Btrieve 6.10 When a Btrieve application is running, a users name is displayed in the monitor utilities when querying about user information. If a user has been logged out from the file server with the SPX session still intact, no user name appears in the monitors user name list. The space for the userss name is filled with blanks. Btrieve itself does not keep track of user names, only network addresses. It is the monitor utility (BTRMON) that is querying the bindery to find the user name information. So Btrieve is not aware that a particular user is associated or NOT associated to the address it is talking to. 20 Btrieve Developer's Journal Case Insensitive Ordering with NetWare SQL CURRENT VERSIONS NetWare SQL 3.00 Case-insensitive sorting of string fields (i.e. SMITH is sorted the same as Smith) is accomplished in NetWare SQL by creating an index on the table with the CASE attribute specified for the field. For example, CREATE INDEX NameSort ON Patients (Last^Name CASE). Subsequently, SELECT * FROM Patients ORDER BY Last^Name will use this index and return the data sorted without regard to case. If no index exists for the fields specified in the ORDER BY clause, NetWare SQL creates a temporary sort file to achieve the proper ordering. Here, there is no way to specify that the temporary sort file be built with caseinsensitivity. So, the application must first create the index with the CASE attribute, and then issue the select statement. In some cases, this procedure is not possible; for example, in a joined view where the ORDER BY fields are not all from the primary table, there is no way to create such an index. In this case, the application could create a temporary file with the appropriate index, insert the selected records into this table, and then read the data from the temporary table using its index. Another alternative is to use the Relational Primitive functions. The xOrder primitive allows the CASE attribute to be specified for sorting the view; this applies to both existing indexes and temporary sort files. Get Previous After Inserting Duplicate Key Values Btrieve Data Management Products Btrieve Engine for DOS....................6.15.1 Btrieve Developer Kit for DOS.........6.15.1 Requester for DOS..............................6.16 Btrieve Engine for Windows.............6.15.1 Btrieve Developer Kit for Windows..6.15.1 Requester for Windows...................6.15.1 Btrieve Developer Kit for OS/2............5.10 Btrieve for NetWare NLM.................6.10c DOS BREQUEST............................6.10e Windows WBTRCALL.DLL.............6.10b OS/2 BTRCALLS.DLL.......................6.10b Scalable SQL Relational Data Management Products Scalable SQL for Windows.................3.01 Scalable SQL Developer Kit for Windows...........................3.01 Requester for Windows......................3.01 Scalable SQL for NetWare (Server Edition).....................3.01 Requesters: DOS SQLREQ.EXE....3.01 SQLREQS.EXE...3.01 Win WXQLCALL......3.01 OS/2 XQLCALLS........3.01 XQL for DOS....................................2.11b XQL for OS/2......................................2.11 Query and Reporting Tools Btrieve 5.x A GetPrevious (opcode 7) operation immediately after inserting a record with a duplicate key value should return the previous duplicate. However, under Btrieve v5.10, the record with a smaller key value is returned instead. For example, if a file has two records with key values AAA and BBB and then three records are inserted with the same key value of CCC, a GetPrevious operation after the third insert should return the record with the second instance of key value CCC. Btrieve for DOS v5.10a returns the record with key value BBB instead. The correct record is returned on the GetPrevious operation with Btrieve v6.x. When using Btrieve v5.10a, a workaround would be to issue a GetPosition (operation 22) followed by a GetDirect (operation 23) after the insert and before the GetPrevious. Then, the GetPrevious returns the appropriate record. Xtrieve for DOS................................4.11e Xtrieve for OS/2................................4.11e HOW TO REACH BTI Btrieve Technologies, Inc. 5918 West Courtyard Drive Suite 400 Austin, Texas 78730 Phone: (800) 287-4383 (512) 794-1719 Night: (512) 794-1731 Fax: (512) 794-1778 CompuServe: GO BTRIEVE You may also contact Btrieve Technologies via the Internet. The BTI Internet Domain Name is btrvtech.com and user names consist of the persons first initial followed by up to seven characters of the last name. For example, Mad Poarchs address is [email protected] Vol. II, No. 4 October-December 1994 (800) 828-7438 or (615) 386-3100 FAX: (615) 386- marketplace to try to buy Intuit, the makers of Quicken, as well as take over the electronic cash disbursement and tax filing systems associated with Intuit. In addition, Microsoft has aggressively gone after a new relationship with BTI. If Microsoft thinks this sounds like a good area to be involved with, you should pay attention - your Btrieve skills may be the key to your cashing in on the excitement. 1994 - Universal Btrieve Use by ASVs Btrieve Based Accounting By Eric E. Cohen, CPA Email: [email protected] CompuServe: 73631,67 In 1994, every major accounting software vendor (ASV) announced the adoption of Btrieve as their database manager of choice. In addition, that years spin-off of Btrieve Technologies from Novell makes the future installation of that Btrieve-based accounting far more likely on non-Novell operating system platforms. These changes in the marketplace make a look at accounting software important for the Btrieve developer. This column is the first in a three part series on Btrieve-based accounting and business information management software. Over the next three issues, it will introduce accounting software and peripheral offerings, including low, medium and high-end selections, and highlight opportunities for developers to be involved. The second article will concentrate on low end products and vertical applications, and provide a resource list for finding out more. The third article in this series will deal with high end packages, add-ons that augment the softwares capabilities, and management of practice issues. Btrieve developers have two primary reasons for reading this series of columns: to find out about new areas of opportunity for expanding business (the ASVs are advertising this ability on your behalf!), and to learn how the new software offerings can help better manage the developers own businesses. After all, every business (including yours) has to keep those books and records for tax time. Developers often suffer the Shoemakers Children syndrome: internal systems suffer compared with those done for clients. There are those two great inevitable events: death and taxes. Death is limited to twice for humans, according to Biblicists, and nine times for cats, according to fable. Taxes come into play at least on an annual basis. What does this have to do with software? Microsoft Corporation thinks enough about the (800) 828-7438 or (615) 386-3100 FAX: (615) 386-3135 Btrieve has been an important offering to accounting software vendors, as is evidenced by its almost universal acceptance by the industry. While describing the attributes that make it so attractive to the readers of this publication is preaching to the choir, business information systems like accounting software have been and will be as important to Btrieve as Btrieve has been to accounting software. Toward the beginning of microcomputer accounting, there were COBOL and BASIC, the remains of minicomputer code brought over to the new microcomputers. Solomon Software was the eccentric, using MDBS as their database manager. Then Softcraft offered a new choice: Btrieve. ASVs who were not hindered by ported minicomputer code were able to move more quickly to Btrieve. On the high-end of off-the-shelf products, Great Plains (Great Plains Software, 800456-0025) and Platinum (Platinum Software, 800-999-1809) were early users of Btrieve. Xtrieve was their readily available report writer. Macola (Macola, Incorporated, 800-468-0834) joined the Btrieve bandwagon in 1989. Btrieves speed and integrity were the greatest reasons Macola and Platinum gained reputations as worthy replacements to minicomputer-based software, at a fraction of the cost, with speed and reliability to match. RealWorld (RealWorld Corporation, 800-678-6336), Solomon III and IV (Solomon Software, 800-879-0444), and ACCPAC Plus (Computer Associates International, Inc., 800225-5224) introduced Btrieve versions over the last two years. Other high-end accounting holdouts, M*A*S 90 (State of the Art, Inc., 800-854-3415) and CYMA (Cyma, 800-292-2962), have announced their future adaptation of Btrieve. Mr. Cohen is the owner of Cohen Computer Consulting, an accounting software consultancy in Rochester NY. He trains CPAs (certified public accountants) and CAs (chartered accountants Canada) in trends in computer technology and accounting software. His articles have appeared in Accounting Today, Audio Microcomputer Report, Buffalo Business First, CPA Software News, CPA Journal, Journal of Accountancy, Rochester Business Journal, Small Business Controller and other business and professional publications. He wrote the book Guide to Customizing Accounting Software, and portions of numerous other books on implementing computer technology. He can be reached on the Internet at [email protected]. Vol. II, No. 4 October-December 1994 Btrieve Developer's Journal Why was Btrieve so important for accounting? LANGUAGE INDEPENDENCE Btrieve did not care what programming language you used to speak to it. That meant that ASVs could use their legacy COBOL or BASIC code with Btrieve, while considering newer technologies. This provided an upgrade path to both the developers and the end users while new programming languages were being phased in. SPEED As the flexibility of the accounting packages increased, the reviewing magazines changed their reviews to reward speed. Since an Editors Choice award could mean millions of dollars in additional sales, Btrieve brought an instant advantage over the non-Btrieve competition. Speed is an important issue to the large companies considering microcomputer-based accounting software as part of their right-sizing or down-sizing activities. Mainframes and mini-computers have their place in high-transaction volume businesses; Btrieve on a micro dared to compete. INTEGRITY Users of COBOL, BASIC and MDBS systems on microcomputers are accustomed to corrupted files and lost data. Btrieve has the reputation being bullet-proof. As missioncritical jobs, computer applications on which the company depends for basic business operations, moved to microcomputers, a high level of integrity and reduced risk of data corruption was necessary. Btrieve met this requirement, along with standard tools to recover data. NOVELLS SEAL OF APPROVAL In the early 80s, the single-user, single-tasking MSDOS operating system environment was a frustration. Many companies tried to offer ways around this limitation, with multiuser DOS extensions and local area network solutions. However, few businesses were comfortable with any method of having multiple DOS users share a common database. The failure of OS/2 in 1987 to meet the multi-user expectations of users may have been the catalyst that propelled Novells NetWare into the limelight. Novells networks, once known as notworks, emerged as the most popular way to get multiple users into an accounting database for those who wanted to use DOS applications and stay away from Unix/Xenix. Novells purchase of Btrieve that same year made choosing Btrieve as a database manager the logical choice for anyone wanting to make sure their accounting software would be compatible with Novell for years to come. THIRD PARTY SOFTWARE AND TOOLS TO ADD CAPABILITIES Partnerships can make each partner stronger. ASVs saw the opportunity to use partnerships to make their own business situation stronger. If the ASV did not have to develop their own contact management package, depreciation module or report writer, they could concentrate on their basic product. In addition, they could capitalize on the popularity of a third party 22 Btrieve Developer's Journal product as being compatible with their own. Clever developers can add capabilities to others software - if it is in a standard database file structure, like Btrieve. One example, an executive information system (EIS) called Forest & Trees (Trinzic Corporation of Waltham, MA, 800-952-8779 or 617-891-6500) provides a visual dashboard to a business's operations. Borland International Inc.s defunct ObjectVision was another powerful tool for augmenting the accounting software packages capabilities. CONSULTANT AND END-USER PRESSURE When are you going to have a Btrieve version? Finally, ASVs moved to Btrieve because consultants and endusers were demanding it. As third party Btrieve tools like report writers became more sophisticated, users had to invest more in mastering the technology. For consultants supporting multiple accounting packages, having them all on Btrieve meant a greater return on software and training investments. BUT - WHAT OF THE FUTURE? In the DOS world, where there is limited interapplication communications (IAC), a standardized database was vital to provide common links between products. How about in the Windows world - the land of Dynamic Data Exchange (DDE) (or was that Dwight David Eisenhower?) and Open Database Connectivity (ODBC)? Btrieve provides speed underneath the Windows veneer that current IAC cant match. How about referential integrity in the database, password security and database dictionaries? Where Btrieve works fine for smaller and growing companies, big companies are concerned about software passwords being bypassed by data access tools. Using products like Microsoft Access to get at accounting data using Btrieve opens the door to anyone to see what the boss makes. Access also limits the number of fields you can access in a file. The youthful BTI has the tall task of making Scalable SQL compete with the Sybases and Oracles of the world with their mature development tools. Possibly it will be the support of the ASVs that will propel BTI into greater dominance. Accounting software vendors need an open architecture to make sure future technologies dont pass them by. What are the trends we are seeing in accounting software development? ACCOUNTING SOFTWARE TRENDS Windows The race is on to sell Windows-based accounting. Only a few vendors have had any success in putting even a limited subset of their DOS functionality on the Windows market. As with all development, ASVs are feeling the push for graphical user interface (GUI, largely under Microsoft Windows) development. Windows brings a characteristic loss of speed to most accounting applications. However, the belief that Windows-based accounting should be easier to use than DOS (by definition) has propelled GUI accountings popularity. Developing around Windows means a proper multiple document interface (MDI), so that multiple accounting screens can be viewed simultaneously. An order entry person can field phone calls while switching to another window for cash entry in free moments. Windows also brings font and printer control and Vol. II, No. 4 October-December 1994 (800) 828-7438 or (615) 386-3100 FAX: (615) 386- a more standardized menu structure for finding your way around. One of the biggest areas in Windows development, however, is the screen customization and programming-like functionality built into the new breed. The next generation packages are bringing screen modification tools not unlike Visual Basic or Microsoft Access: fields can be moved, hidden, renamed, defaulted, and code can be added behind forms and fields to add functionality. This ability to augment the software is highly publicized, opening doors for developers to create new functions for the software that does not interfere with the programming source code. Large Company Features Just as the Honda Civic of the 90s is the size of the Honda Accord of the 80s, so accounting softwares features are migrating upward. The high end packages are trying to become the foundation for international companies downsizing effort. This has been met by vastly increased field sizes and efforts to incorporate new technologies. Increased field sizes are one of the most important items for working with large companies. Chart of accounts, purchase orders and invoice numbers are unusually (and unnecessarily) long in larger businesses. In addition, conversion of dollars to Lira or rubles can choke most systems. (800) 828-7438 or (615) 386-3100 FAX: (615) 386-3135 Other international features by definition mean expanded foreign currency capabilities, foreign language options (like Kanji or cyrillic), and tax and business reporting needs for other countries (like VAT). Emerging technologies Accounting software can no longer stand on its own. Demands by large companies on other large companies and on small companies has meant that most businesses are being confronted with todays technologies of the future. Bar coding printing and data input makes data collection tasks like taking a physical count of inventories far more efficient. In addition, some large companies will only do business with companies that bar code their shipments and documents. Electronic Data Interchange (EDI) is the application to application exchange of business transactions using public standards for information content (EDI World, June 1994) - or, in other words, a set of standards, with names like ANSI X12 and EDIFACT, for the way information is formatted and communicated by computer between businesses. These packets of information include purchase orders and acknowledgements, inventory inquiries, invoices, and notification that cash is being transferred to pay a bill. In tones reminiscent of CB radio, youll now hear Accounts Payable Vol. II, No. 4 October-December 1994 Btrieve Developer's Journal clerks asking, Wheres your 820 (EDI payment advice), good buddy? EDI spans barriers, like time zones, language differences, or personnel cutbacks in data entry staff, hindering communication between business partners. It also automates business tasks, like inventory look-ups. With EDI your customers can send electronic request to review your stock availability without tying up your personnels time or making you face the technical and security problems of giving customers direct access to your computer system. Computer mailboxes on third party communications services like IBM, GE, AT&T and Control Data provide 24 hour a day dial-up capabilities for one step drop-off and pickup of the packets. These VANS (Value Added Networks) act as intermediaries and can provide many additional helpful services. Using these mailboxes, for example, companies in Japan, Africa and India can leave purchase orders for a vendor in Colorado during their respective business hours, which the Colorado company retrieves when they open the next day. As with bar coding, many large retailers like Wal-Mart and K-Mart will only do business with companies that can receive orders and acknowledge those receipts via EDI. Document image processing systems use the computer as an electronic filing cabinet. Hooked in with accounting, users can view supporting documentation (scanned into the computer) when reviewing the results of operations. Lotus Notes integration (and other electronic mail enabling) gets information to the people who need it electronically. These necessary hooks into accounting software make it a ripe marketplace for developers to provide instant solutions, while the ASVs determine their own future direction. ACCOUNTING IMPORTANT FOR BTRIEVE DEVELOPERS Although accounting software is no longer the primary driver for computer installations, it is still a main driver. Your clients are probably asking for advice on which package to buy and how to best customize their software to meet their needs. You need to keep your house in order, too. Following is a brief review of accounting softwares major pieces. ACCOUNTING SOFTWARE MODULES AND WHERE THEY FIT IN Accounting software is general sold by modules, which are associated with a business department or set of tasks. Although each vendor offers a different set of products, it is important to know the most popular modules and their role in business. The Big Three in accounting are the General Ledger (GL), Accounts Receivable (AR) and Accounts Payable (AP) modules. These are the most popular modules and found in most businesses and departments. Most larger businesses track their accounting on the accrual basis. That means that sales are entered when they happen and expenses when they are owed. Smaller businesses and service-based businesses often do their accounting on the cash basis. In cash-basis accounting, sales and expenses are recorded when cash is transferred, not when it is owed. Although accountants generally agree that accrual basis accounting is better for managerial oversight, it is important that the system can track your business results in the way you need to report it for tax and reporting purposes. General Ledger The General Ledger (GL) is the place where all of the financial information of the company gets summarized. Information from all of the other modules flows to the General Ledger to be analyzed, summarized, and presented in financial statements. Budgets and prior year information is maintained in the GL so management can compare the results of operations with prior years and with forecasted results. Most GL packages will let you automatically bring over accounting information from other modules without retyping. Some will also let you bring in summary information from other systems in a ASCII, Lotus worksheet or dBase III format. Development opportunities: interfaces from custom developed packages; automatic links out to spreadsheets. Accounts Receivable and Cash Management The Accounts Receivable (AR) module is the storehouse for customer related information. Depending on your industry, your customers may be known by other terms, such as clients or patients. The basic information about your customers (like addresses and primary contact names)and salespeople are kept here. Cash receipts, finance charges, monthly statements 24 Btrieve Developer's Journal Vol. II, No. 4 October-December 1994 (800) 828-7438 or (615) 386-3100 FAX: (615) 386- and aging reports are processed here. For smaller installations, some basic invoicing capability in the AR module may be helpful. AR works closely in conjunction with Order Entry and Billing systems. Cash Management tools may be as simple as cash expectation reports to full credit monitoring systems. Development opportunities: visual dashboards of cash position, links from custom order entry systems, integration with EDI systems for cash received. Accounts Payable and Bank Book. The Accounts Payable (AP) module automates the check writing process. The AP system can print checks for you or track checks you have written by hand, as well as recording bank charges and electronic transfers. Accounts Payable works closely in conjunction with Purchase Order systems. Bank book systems help with check reconciliation and maintaining bank balances. Development opportunities: Integration with ASCII files from banks for check reconciliation; links from AP to AR for agents, billbacks of expenses. Payroll and Human Resources The fourth entry in the Big Three is payroll (PR). Although most accountants recommend that smaller businesses use outside firms to process payroll, due to the ever changing payroll tax laws and rules, internally prepared payroll is helpful for job oriented businesses. Payroll systems collect employees time, print payroll checks or direct deposit stubs, and prepare reports for taxing jurisdictions, government requirements and management purposes. Human Resource (HR) systems track additional information, such as the results of reviews and raise histories, as well as skills and training. Payroll systems feed information to job cost systems for analysis of the actual costs of a job, including labor, materials and overhead. Development opportunities: integration of timeclock systems; Union and other special reporting. Inventory Management For businesses that resell or manufacture, keeping track of the costs and usage of inventory is important. Inventory Management (IM) systems track the quantities on site, the current demands for each item from internal and external sources, and expected replenishments. They also assist in doing physical counts. Each industry has special tracking needs. Retail environments may need to have multiple item numbers (UPC, internal, manufacturers) for the same item. Manufacturers need to track the identifiers of engineering drawings and instructions for manufacturing (routings and bills of material) for each item. Users need to be able to quickly discern the investment in their inventory, as well as the availability of items for use or sale. Development opportunities: work in process systems; receiving and purchasing systems. Order Entry Presumably every business is in existence to make money. Tracking the requests for product or services and the fulfillment of those requests goes by different names for each industry. Retail businesses have point of sale, where most See Accounting on page 36... Programming for Hire By Jon Burke, Business Logic Email: [email protected] CompuServe: 75470,3115 The computer industry hasnt turned out at all as I expected. Since the early 1980s when personal computers where just making their debut, I expected the computer industry to go the way of the automotive field. With automobiles, the small, creative independent manufacturers were pretty much on their way out by the late 1940s. By the 1960s the independents were completely gone, and only the giant mega-corporations remained. Thats how I expected the computer industry to fare. But I was wrong. Instead of the large scale calcification I expected, the giants in the computer industry rose up, were struck down, and left in their wake a A large part of conglomeration of small, hungry, innovative firms that are vying successfully for overall the industry has control of the industry. gone to small shops and Certainly, IBM, DEC, and Hewlett Packard are still around. independent consultants. However, a quick These gunslingers are grab- look through any trade paper will show hundreds and bing a larger and larger thousands of small companies some still working piece of the pie. nearly out of back yards hassling the major players in the field, and often winning. And this trend seems to me to be on the upswing. Software application development is following the same trend. Large companies such as Platinum have recently had their difficulties, and many arent doing very well at all. A large part of the industry has gone to small shops and independent consultants. These gunslingers are grabbing a larger and larger piece of the pie, and this has given rise to an unusual problem. In spite of the fact that small companies have been a part of the American business scene since before George Washington, it seems that not many people know much about how these companies operate. Everyone knows how to buy a car from General Motors, but how many would know what to do if they wanted a Tucker instead? The same applies if youre the one making the car how do you get started and stay started? (800) 828-7438 or (615) 386-3100 FAX: (615) 386-3135 Consider these questions taken from a letter I recently received: How much should I pay a programmer to write code? How should I handle any bugs I might find, in terms of a contract? What other items should a contract contain? Where do you find a good programmer and how do you tell? What about confidentiality and nondisclosure? These are very good questions not just for the potential consultant or programmer but also for the party who hires the contractor. Before I start trying to answer these questions, Id like to lay some ground work and discuss the overall matter at hand. To my mind, the central issue in contractor-to-contractee relations is trust. The contractor runs a risk in undertaking a contract. Will he get the estimates right, or will he wind up working for next to nothing? Will his client pay on time or at all? How does the contractor protect himself? For the client, the questions are just as tough, if not tougher. Typically, the client is hiring knowledge and experience over and above what they have available to themselves. This means that whoever they hire will be performing magic something they will find difficult or impossible to evaluate during the development cycle. So they have to rely on trust, and trust doesnt come easily. Will the contractor get the job done at all, and if so, will it be on time? And the Big Question: How Much Will It Cost? While these questions remain unanswered, tensions inevitably rise, and the job at hand gets a lower and lower percentage chance of successful completion. Its been my experience that, if the client and the contractor are both seriously afraid about how the job will come out, trouble is on the way. The converse is likewise true: If everybody concerned is convinced of each others ability and good will, insurmountable problems seem to fade away and the likelihood of the project reaching a successful conclusion approaches certainty. So, I believe its absolutely fundamental to create and maintain trust throughout the life of a project. A lot of my answers to other questions revolve around this way of thinking. Keep this approach in mind and a lot of the other questions start to answer themselves. How much should I pay a programmer to write code? On the surface, this looks to be a simple question, and I guess I could just brush it off with a quick dissertation on programming rates. However, the real meat of this question isnt so much the rate one pays or receives for programming services, but rather how the overall project gets paid off, what it costs in the long run, and how payment is tendered. To my mind, this is a much more important question. Ill answer both. Programming rates vary considerably based on a variety of indices. Geographic location, the programming language in question, the type of task to be programmed, all play a part. Typical programming pay (money received by the contract programmer) in Southern California runs from maybe $22.00 per hour on the low end to perhaps $150.00 per hour on the higher end, with the majority getting between $32.00 to about $65.00 per hour. Usually, the programmers receiving the lower pay rates are acting as subcontractors, so its rare that the Vol. II, No. 4 October-December 1994 Btrieve Developer's Journal client will pay rates in the twenty to thirty dollars an hour range. payment, the client got more and more uncomfortable. Huge sums of money were piling up, and there was no commitment You can expect client rates to be between 20% and 40% higher than what the subcontractor programmer receives. Keep in mind on the programmers side, other than his professionalism, that the project would actually reach completion. The project finally that these figures are pretty rough. There are other factors that come into the equation besides finished, about 15% over budget (a not unusually high overage in this kind of project), but the client raw cash. Flexible hours, work that can be was a nervous wreck, and the performed off-site, location of the site, relationship had deteriorated and the type of work all figure into it. If the ΤΟ ∆Ο ΛΙΣΤ substantially. I dont recall the work can be performed away from the ι. δατα κοµπρεσσιον αλγορυθµ programmer getting any more work client site, or if the hours during which the ιι. ρεΦορµατ ′αρδ δισκ ιιι. ∆ΕΒΥΓ ΠΡΟΓΡΑΜ from that client, and the software programmer must work are not cast in σωκ θε βυµς φορ α λοτ οφ created during that project deteriorated stone, this can count for a large reduction δραχµα βοι αρε θη γοννα ω µε from neglect. Within one year, the in rate of pay. Alternately, if the work φορ θις client company removed the software. must be done between the hours of 9:00 Everyone lost. The alternative, and 5:00 every week day at a factory however, is justifiably scary for the location, the client can expect to pay contractor. How can you say what will premium prices. happen in three months? Six months? A Long term contracts typically year? In my experience, the vast pay/cost less per hour than short term majority of project estimates turn out to jobs. In this case, the programmer trades be wildly wrong, and almost all of some income for security and a larger them are optimistically so. overall payoff, and its usually a good The only way around this is designing trade for all concerned. I typically discount the project in great detail before projects that take three months or more by bidding it. Typically, Ill design the as much as 25%, all other factors being database and lay out all the DDFs. Ill equal. complete screen layouts and report Youll notice that until now, Ive samples. Ill write up the proposed flow discussed hourly rates exclusively. I do Project estimation is nearly a of operations in clear, nontechnical this because I dont think you can estimate black art in the programming terms. I include a total project bid, a or track a project in any other way you business list of milestones, and a payment have to consider the hours involved and price accordingly. However, hourly pay is not my favorite method schedule. This later says what completed work the client will be of remuneration although its certainly the most prevalent in the shown in exchange for a check of a designated amount. I try to industry. The reason it is the most common payment method is that time it so a milestone and its accompanying check show up fixed bid projects must be effectively estimated. And project about every week or two. You should seriously avoid letting milestones spread out over more than 30 days under any estimation is nearly a black art in the programming business. circumstances. Folks who contract to build houses or lay asphalt, In preparing one of these specifications, I think its armed to the teeth with experience and automated estimation programs, complain mightily about how tough project estimation wise to err on the side of extra detail. This sounds like a huge amount of work, and it is. However, until you do this, there is is, and how inadequate their resources are. Theyre right its absolutely no way you can effectively estimate what a job will tough but it may be twenty times tougher for the contract cost. programmer. At least, a company laying an asphalt road has While I may not know what it will cost to complete the laid many roads before. It may go up or down, the bedding may be soft or hard, the climate may be cold or hot, but a road, after entire project, I can generally guess pretty closely how long this estimation phase will take. So I tell my client the truth: I cant all else, is still a road. Programmers, on the other hand, are estimate the project cost until the specification phase is typically asked to perform tasks in completely unrelated fields. complete. It will take me x number of days/weeks/months to Looking over our books, I see my company handled over the complete the estimate, and it will cost this amount. The amount course of one year a program to evaluate the density of biota in varies depending on the project. Usually, charges run between an estuary, a shop floor control program that interfaced with $1,500 and $15,000 for a specification. Typical terms are 25% robotics equipment, a project to track cost of production on to 50% to start and the rest on submission of the specification. wood products, and the rescue of a database that a client had You should anticipate changes in your first draft of accidentally encrypted. And thats in addition to ongoing work. specification, mostly due to misunderstandings, missing a small All of these required different skill sets. but important point, etc. These, I correct for no extra charge. These are all good reasons why fixed bid work isnt in For major changes in the concept of the project, you should bill vogue today. However, I think the reasons in favor of fixed bid projects outweigh the dangers. It all comes back to trust. Hourly extra. A whole primer on project estimation is beyond the billing tends to be a lot more protective of the contractor, and it scope of this article. However, Ill mention a few of the tends to put the client at a higher level of risk. I recall a project concepts that represent the toughest hurdles I generally that progressed on schedule, with milestones being met and the encounter when estimating a project, in hopes that theyll help programmer getting paid every two weeks. But with each 27 Btrieve Developer's Journal Vol. II, No. 4 October-December 1994 (800) 828-7438 or (615) 386-3100 FAX: (615) 386- even a little. Nothing happens that takes less than four hours In larger projects, this can go up to a day. If you think that a simple report, for example, can be completed in one hour, more power to you. However, you should remember that a single mistake means getting the error report, fixing it, recompiling (or the equivalent), sending the fixed version to the client, and getting the report that says the error is fixed. I can barely write that sentence in under one hour. In a fixed bid situation, its wise to build in some time for error control. Add a percentage to the overall project cost to cover mistakes. Tell your client about this too. In a fixed bid situation, its difficult to go back for more money once the project is underway. You absolutely have to build in a buffer for when (not if) mistakes happen. From the clients point of view this is equally wise major accidents can easily wipe out a project budget. Keep a safety buffer. Work from previous projects. Its a good idea to go back and reestimate previous projects, especially those that werent fixed bid. It gives you an idea of what reality is like and is sharpens your skills considerably. When a project estimate is high, consider that it might also be accurate. This works with the last suggestion. A typical mistake I still make is to look at a project estimate and get blown away by the huge numbers I come up with. Okay, sometimes theyre wrong. Other times, however, they turn out to be uncomfortably close to reality. Look at some past projects that werent fixed bid. How much money and time really got spent in the long run? Youll note that a lot of this talk about planning can apply to hourly work as well as fixed bid projects. However, once Ive submitted a specification that states how long certain phases of a project will take, I find that Ive inadvertently crossed over into the land of fixed bids without noticing. So it becomes the same thing after all. How should I handle any bugs I might find, in terms of a contract? The client has a reasonable right to assume (and insure) that their shiny new software works once its installed. Likewise, its also reasonable and fair for the programmer to consider the project complete after a certain point, and not to be haunted by a project like Marleys ghost. The best way Ive found to handle this is to issue a warranty that fixes any bugs that occur over a specified period of time, usually thirty to ninety days, for no extra charge. Bugs discovered after that time period are billable. This may sound a bit harsh, but its not really not if its done right. I tell my clients the following: The system 28 Btrieve Developer's Journal WILL have bugs. Everyone must expect them and plan for them. Ive never seen a large custom system written entirely bug free, and I doubt that such a thing is possible. Bugs are, unfortunately, part of system development. Test everything I install as much as possible during the warranty period. If you dont test then, finding a bug after the warranty is almost a certainty. Bugs must be repeatable. If I cant see the bug and make the bug happen, I cant fix it. However, when nonrepeatable bugs occur during the warranty period, I log them. Later, if I find their cause, I almost never charge to fix them. Dont commit valuable, unprotected data to a system until youre certain the system is stable. The real reason I put a time limit on this (and I tell my clients this too) is that I want to fix all of the errors while its still fresh in my mind. I cant think of anything more disconcerting than having to fix a bug on a project I worked on five years ago in code the client is just now getting around to testing. So Im not too inflexible about the exact timing on error reporting. If the client finds a bug on the ninety-first day, Ill consider it warranted, as long as the testing effort is underway. What other items should a contract contain? First, I should say that I favor agreements versus formal contracts, even on larger jobs. Agreements can be just as binding as formal contracts if theyre done right, and they seem to set a friendlier tone. I suppose that, if I took on a job with a client I didnt trust, I might go with a formal contract, but I cant see myself taking on such a project in the first place. In either case, contract or agreement, Ill skip over the boilerplate that all these seem to contain youre better off getting that from a lawyer or at least a preprinted form prepared by lawyers, than you are from me. Instead, Ill simply mention the points I think are most important: Include specific references to the specification as the project definition. The specification defines the scope of work and the project. If the spec doesnt say it, it wont get done. Dont try to describe the project in the agreement it just doesnt work. A specific reference to the Payment Schedule should be part of your specification. Payment terms. Mine are due upon presentation of invoice. I try to include these in the agreement. Total payment amount. Likewise, I include this too. I tend to avoid penalty clauses I think they make for bad feelings. I dont charge penalties for late payments, as thats almost never been a problem for me. I wont accept a contract that includes a performance penalty or late penalty that effects me adversely. Either way, this gives the parties concerned a reason to find fault in each other. Thats not a healthy relationship. Confidentiality. I note in any agreement that all I have written is proprietary and confidential, and that release of this information will cost me sums far in excess of the project cost. Thats the truth too how long does it take to develop a file access routine that you use in all your work but dont bill for directly? I require that my client treat my information as proprietary and confidential, and that they take measures to insure that it stays this way. Source Code. I specify who gets the source code at the end of the project. Personally, I prefer that the clients have it they seem to feel more comfortable when Vol. II, No. 4 October-December 1994 (800) 828-7438 or (615) 386-3100 FAX: (615) 386- they dont feel trapped into using me and me alone. Theres much more that is typically included in such documents, but these are my favorite topics. Anyone seeking more information should contact a legal professional. Where do you find a good programmer, and how do you tell? This question addresses a rather subtle problem: How to you test for expertise in a field where you have little or no expertise yourself? While I dont know of a scientific answer to this, there are a few things you can do. Get References and call them. While any contractor in their right mind will only give references that speak well of them, you can still get lots of information about a contractor from anyone they have done business with before. Check source code. I often ask programmers to bring me a sample of source code theyve written that they are happy with. Even if you dont program, you can tell a lot from this. Are there lots and lots of comments? Is the code neat looking? I know this last may sound silly, but try to lay out a large case statement without the proper indentations and see if you can understand it yourself! Ask the programmer to explain why they are happy with this code. If the programmer can explain clearly without reverting to technospeak, thats a real plus. Find out if you share any mutual contacts and call them. Programming is a small world its not unusual for me to find out that a prospective contractor knows some of the same people I do. If thats the case, I call them up and ask their opinions. loss. When the plaintiff made your confidential documents available to others, what damage did you incur? The fact that damage will result if your work is revealed should therefore be included in the agreement. Another important thing to remember is that you cant restrict a person from doing his or her job. I recall my lawyer showing me an agreement that tried to exclude a programmer from working as a programmer after he left the firm, based on the idea that all the techniques he learned were proprietary. Needless to say, this didnt stand up. When writing a nondisclosure agreement, I try to make sure that what I restrict is very specific and does not effect the contractees overall work picture. One last thought on the matter: Nolo Press of Berkeley, California produces a book called Software Development a legal guide. Its written by attorney Stephen Fishman, and its really excellent. More important, it also contains sample contracts, agreements, and nondisclosure contracts. Unless your lawyer is s specialist in intellectual properties and the data processing industry, this book may well tell you more than your own lawyer can. The cost is offset by the sample contracts alone.² Jon Burke is an independent programmer, consultant, and occasional free-lance industry journalist. Jon is president of Business Logic, 5 Vista Del Ponto, San Clemente, CA 92672. He may be reached at: (714) 492-0442 CompuServe: 75470,3115 Internet: [email protected] What about confidentiality and nondisclosure? Again, Im not a lawyer and this is an especially tricky aspect of law. However, Ill be glad to pass on what Ive gleaned over the years. Youre advised to seek further council from professionals before acting on anything I say here. Excluding the cases where national security is an issue, violation of confidentiality and nondisclosure agreements are both served in civil court no criminal penalties, at least as far as Ive ever heard. If youre trying to non-disclose a single programmer and they dont have the financial wherewithal to make a law suit viable, and unless you can prove they actually profited directly from a disclosure of protected information, there isnt too much you can do. The biggest damage one typically incurs from violating nondisclosure agreements is that he or she doesnt get to see any more secrets and, as this industry is a close knit one, others hear of the violation and react with distrust. If, on the other hand, youre concerned about confidentiality as it pertains to another firm, there is a lot you can do, starting with the typical nondisclosure agreement. These are often boilerplate, and you can get preprinted versions. Also, take a look at any of the larger companys agreements that come out with beta tests, some product pre-announcements, etc. If you have access to one of these, taking an example from them can help. (Note: copying them may not be legal.) Like any other civil matter, judgment will depend upon (800) 828-7438 or (615) 386-3100 FAX: (615) 386-3135 Vol. II, No. 4 October-December 1994 Btrieve Developer's Journal transactions are fulfilled immediately. Wholesalers have order entry or customer order processing, where documents called picking tickets are prepared after the order is entered, and the order is billed after it is determined what can be shipped. Professionals use time and billing systems, and those in construction, job costing. Those in the computer industry need quoting, service dispatch and time and billing. These modules will be covered in more detail in the next issue. Development opportunities: Electronic data interchange integration; special query tools to help customer service quickly find open and closed orders. Small tweaks of the software to make operations more efficient can be done easily in the Windows environment. The ASVs let you add functions to menus to run your program from within the main software. Many ASVs are marketing their own programming development environments for their packages. Whether it is Dexterity for Great Plains Dynamics or upcoming tools from Libra for their new Windows software, end users will be finding that development is not as easy as they think. Mastery in one of these environments may be a key to future business. Purchase Orders A number of developers have written applications to meet special needs that work in conjunction with off-the-shelf accounting. This means they do not have to take on as much responsibility, and can co-market their products with the ASVs. When it is time to replenish inventory, buy goods needed on jobs, or request outside services, companies user Purchase Order (PO) systems to track the companys commitments. PO systems are used for printing and tracking open orders, keeping files on available and historic pricing, and entering receipts (and possibly the payable due upon receipt). Development opportunities: EDI integration; receiving systems; custom databases of pricing and history. THE OPPORTUNITIES Accounting Software is a lucrative environment for the developer. Very few companies are 100% satisfied with the feature sets of off-the-shelf software. In fact, if you polled the potential users of accounting software for their wants and needs list, you would rarely find a package that met more than 8085% of their needs. The developer can help in three ways. Modifications 30 Btrieve Developer's Journal Vertical applications User query tools Todays accounting collects and keeps a great deal of information -just getting at it is a problem. The reports and inquiry screens of most accounting software are often criticized as containing too much. Developers can prepare tools for letting people get at their selected information more easily. Conclusion Every major vendor of off-the-shelf high-end accounting software has moved to Btrieve as the basis for their next generation software. This is an exceptional time for the Btrieve developer to take a look at the marketplace, for their clients and their own sakes. ² Vol. II, No. 4 October-December 1994 (800) 828-7438 or (615) 386-3100 FAX: (615) 386- Letters and Comments Please let us hear from you! We want to make Btrieve Developers Journal just right for you. Send us any news, information, comments, suggestions, or anything else to BDJ, 2416 Hillsboro Road, Suite 201, Nashville, TN 37212 Dear Btrieve Developers Journal, I have quite a few magazine subscriptions, but I can’t find the time to read any of them. I think yours may be the only one that I can get to on a semi-regular basis and I just have to read it from cover to cover. Of course, if I can free up that time, maybe I could have time to read the Table of Contents of my other magazines - just to see what I’m missing. Keep up the good work! Also, there seem to be quite a few people clamoring for ODBC improvements. I assume youre keeping an eye open for the latest status on these projects. Davin Church, Mesquite, TX Davin, Thanks for the kind words... We have been inundated recently with mail on ODBC. Ron Harris, President and CEO of BTI assures us that BTI is formulating a comprehensive ODBC strategy so that this problem will be solved. Here are some other comments that we have received recently: Dear Btrieve Developers Journal, The Intersolv ODBC driver is difficult to install, has quirks in usage, and is not even implemented correctly. For example, they maintain cursor support by issuing a WHERE statement containing the name and value of EVERY field in a table. If you have large records, the buffer overflows and you cannot access your data. BTI has great internal cursor support in Scalable SQL. Someone needs to implement a proper ODBC driver that takes full advantage of that product. Lance Prager, CIS: 71154,1341 Dear Btrieve Developers Journal, I would very much like to use Btrieve with an ODBC driver (using PowerSoft products) but the royalties are ridiculous. Intersolv/ Q+E wants somewhere around $60 per site and I need about 2,000 sites. BTI needs to write their own ODBC drivers. If anyone else is having any similar problems or worries, please let BTI know. Enough people could get the ball rolling. Michael Binette, Stoneham, MA Dear Btrieve Developers Journal, We’ve been using both the Q+E and Microsoft ODBC drivers for Btrieve from within PowerBuilder for months... and we hate it. Both drivers have their problems, so a ‘true’ ODBC implementation from BTI would make us very, very happy. If beta testers are needed, we would be more than happy to volunteer. Rob Rene, Provo, UT Dear Btrieve Developers Journal, As you know, I am working on a book about Btrieve for Addison-Wessley Publishers. Now that things are progressing, I have decided to look in to including a chapter on third-party tools that work with Btrieve and Scalable SQL, both commercial ones (like your DDF Builder for Windows and Smithware Controls for Btrieve) and shareware (such as Doug Reilly’s BTFiler). I would appreciate your passing this information along to any vendors who may wish to be included in this section. I’ll keep you posted on how things proceed. Jim Kyle, Oklahoma City, OK Dear Btrieve Developers Journal, I just received my free copy of Btrieve Developer’s Journal today... and was it worth the wait. You guys sure did a good job on your magazine. Lots of good technical stuff. After reading the center section contributed by BTI, I now have a much better understanding of what Scalable SQL is about. I also liked the article on “Unlimited File Sizes” via a virtual filing system. I am sending in my subscription form tomorrow morning. Since we also purchased your Smithware Controls for Btrieve a few days ago, we are now searching the delivery people coming into and out of our building. It’s been at least two days now since we ordered them and we can’t wait! John Dunbar, Houston, TX Dear Btrieve Developers Journal, Would you be interested in distributing the content of Btrieve Developer’s Journal electronically to your audience through Btrieve’s on-line service? Keven Pietzsch, Columbus, OH Kevin, We are working with Chris Ojeda, BTI’s CompuServe SYSOP to set this up. Look for an electronic edition of all back issues of BDJ by the end of the year. Dear Btrieve Developers Journal, It’s good to see some third party companies like Smithware tackling the information void in this industry. Product is only a small part of what developers want from a company. We want data, data, and more data. Keep up the good work. Robert Lauer, Newton, PA 31 Btrieve Developer's Journal Vol. II, No. 4 October-December 1994 (800) 828-7438 or (615) 386-3100 FAX: (615) 386-