Converting Btrieve Files to Basic ISAM with ISAMCVT (Complete) (69849)



The information in this article applies to:

  • Microsoft Visual Basic for MS-DOS
  • Microsoft Basic Professional Development System for MS-DOS 7.0
  • Microsoft Basic Professional Development System for MS-DOS 7.1

This article was previously published under Q69849

SUMMARY

The ISAMCVT.EXE utility included with the Professional Edition of Microsoft Visual Basic for MS-DOS, version 1.0; and Microsoft Basic Professional Development System (PDS) for MS-DOS, versions 7.0 and 7.1 allows you to convert database files created with several popular database products to Basic ISAM database files.

Pages 147-149 of the "Microsoft Visual Basic for MS-DOS: Professional Edition Features" manual for version 1.0 explains how to use the ISAMCVT utility, and it's options. This information is also included on Pages 391-393 of the "Microsoft Basic 7.0: Programmer's Guide" (for Basic PDS for MS-DOS, versions 7.0 and 7.1).

This article also includes additional information necessary for converting Btrieve version 5.00 and later files.

MORE INFORMATION

There are three steps to convert a Btrieve file to an ISAM file when using ISAMCVT:

  1. Create a specfile that describes the contents of the Btrieve file.
  2. Invoke the PROISAMD.EXE and BTRIEVE.EXE Terminate-and-Stay-Resident (TSR) programs, and execute ISAMCVT.
  3. Fill in the necessary prompts describing how the indexes are to be created.

Step 1: Create Specfile

A specfile is a file that provides information on the contents of the database. The specfile determines the lengths of strings and what data types are to be used. (NOTE: the specfiles for ISAMCVT are NOT the same as the specfiles for ISAMIO.EXE, which are described on Page 146 of the "Microsoft Visual Basic for MS-DOS: Professional Edition Features" manual, and on Page 391 of the "Microsoft Basic 7.0: Programmer's Guide".

Each entry in the specfile corresponds to each key (or key segment) in the Btrieve database. Each entry is on a separate line and consists of the data type, the length of the data type, and the column name that will be used in the ISAM file. Each field on a line should be separated by a comma and should not contain any spaces. For example:
   <Basic data type>,<length>,<column name>
   string,30,Name
				
It is important that the column names in the specfile correspond to the column names that will be used in your program. If the names do not match, you will get an "invalid column" error when you try to open the ISAM file. The following table shows which Basic SIC data types correspond to which Btrieve data types:
   Basic               Btrieve             Length
   -----               -------             ------

   string              string              variable
   integer             integer             2
   single or double    float               4 or 8
   <n/a>               date                4
   <n/a>               time                4
   <n/a>               decimal             variable
   <n/a>               money               variable
   <n/a>               logical             1 or 2
   <n/a>               numeric             variable
   SMBF or DMBF (*)    bfloat              4 or 8
   string              lstring             variable
   string              zstring             variable
   <n/a>               unsigned binary     variable
   integer or long     autoincrement       2 or 4
				
Data types that are tagged (above) as <n/a> have no direct corresponding type within Basic. If the Btrieve file contains these types of fields, they must be converted as strings of the proper length. If you want to be able to access the data within these fields you must be able to "pick apart" the internal structure of the keys and convert them to a Basic data type. Refer to your Btrieve documentation for the details of the structure.

NOTE: SMBF and DMBF are special data types that allow conversion of database files that were created with old versions of Basic [which used MBF (Microsoft Binary Format) floating-point numbers]. When ISAMCVT converts a floating-point number with SMBF or DMBF, it automatically changes it to an IEEE-format floating-point number, which is the format used in Basic PDS for MS-DOS.

All floating point numbers (whether they use single, double, SMBF, or DMBF) are automatically converted to double-precision when they are put into the ISAM database. This is because ISAM files cannot contain single-precision floating-point numbers.

For keys that have a variable length (that is, strings), you should use the maximum length that you specified for that key when the Btrieve file was created.

Step 2: Execute Necessary Programs

Before you execute ISAMCVT, you must load the Btrieve and PROISAMD TSR programs into memory. (If you ran the Basic SETUP.EXE program with the "ISAM Routines in LIB, Support Database Creation and Access" selection, then the ISAM support will be built into the ISAM utilities and you will not need to load PROISAMD).

Refer to your Btrieve documentation for details on how to start Btrieve. To start the ISAM TSR program, just type PROISAMD at the MS-DOS prompt.

After the TSR programs are started, you can then invoke ISAMCVT. The syntax for ISAMCVT with Btrieve files is listed below:
   ISAMCVT /B filename tablename databasename specfile
				
where:

filename - The name of the Btrieve file to be converted.
tablename - The name of the ISAM table that the records
will be put into.
databasename - The name of the ISAM file to be created.
specfile - The name of the specfile (see step 1).

Step 3: Specify the Indexes

ISAMCVT tells you how many indexes there are in the Btrieve file. ISAMCVT then prompts you for the information necessary to convert the indexes. A typical prompt may resemble the following:
   ISAMCVT: Index  Position  Length  Unique.
   ISAMCVT:   1        1        2       0
   ISAMCVT: Index Sample: <a sample key for this index will be here>
   ISAMCVT: Enter the column names for the Index (up to 255 characters):
				
If this key is a string type (string, zstring, or lstring), ISAMCVT will show the contents of the first record of that key in the "Index Sample:" field. If the key is not a string, you will get meaningless characters.

When ISAMCVT asks for the column names, you should type the names of the columns that this index is keyed on. As in the specfile, the column names should be separated by commas and there should be no spaces. If you put spaces between the column names, you will get an "Invalid index name" error. For example:

ISAMCVT: Enter the column names ... : Col1,Col2 <-- correct
ISAMCVT: Enter the column names ... : Col1 Col2 <-- "Invalid index name"

After entering the column names, ISAMCVT will prompt you with the following message:
ISAMCVT: Enter a name for the Index (Up to 30 characters):
Enter the name that you will be using for the index in your program. ISAMCVT will repeat these prompts for each index in the Btrieve file.

Notes for Steps 1 Through 3

  1. As stated in step 1 (create specfile), the following Btrieve data types are not directly supported in ISAM files:

    date, time, decimal, money, logical, numeric, unsigned binary

  2. Basic ISAM files do not allow an index to be stored in descending order; however, you can use the MOVEPREVIOUS command to step backwards through the index.
  3. There should be no spaces between the fields in the specfile, or between the column names, when entering the column names for indexes.
  4. ISAMCVT uses features unique to Btrieve versions 5.00 and later. If you try to convert a file using an older version of Btrieve, you will get a "ISAMCVT: Btrieve error 1 stepping into Btrieve file" error.

Example Converting Btrieve File

The following example gives a step-by-step description of converting an actual Btrieve file.

The first program below (BTRIEVE.BAS) will create a Btrieve-format file. This file will have three keys. The first key is an integer and allows duplicates. The second key has two segments; the first segment is a 2-character string, which does not allow duplicates, and is sorted in descending order. The second segment is a 30-character zstring, which also does not allow duplicates.

To run BTRIEVE.BAS, you must first load the Btrieve TSR program (refer to your Btrieve documentation for instruction on how to do this.) Then start VBDOS.EXE or QBX.EXE with the Btrieve far-string Quick library. BTRIEVE.BAS will create a Btrieve database file called DATAFILE.BTR and insert 10 records. The first key in each record is a random integer between 1 and 100. The second key is the current record number (in hexadecimal), and the third key is a string of asterisks. BTRIEVE.BAS will print each record as it is put into the database, and then reprint the data based on the random number key:
 71 01*                          (This is the data as it is
 54 02**                          put into the file.)
 58 03***
 29 04****
 31 05*****
 78 06******
 2 07*******
 77 08********
 82 09*********
 71 0A**********

 2 07*******                     [This is the data when it is
 29 04****                        read back from the Btrieve
 31 05*****                       file (sorted on the random number
 54 02**                          key).]
 58 03***
 71 01*
 71 0A**********
 77 08********
 78 06******
 82 09*********
				
Before the Btrieve file can be converted to an ISAM file, you need to make a specfile. To do this, compare the data types used in the Btrieve file with the table in step 1 (Creating the Specfile). In this case, there is an integer, then a string (length = 2), then another string (actually, it's a zstring, but the table tells us to convert it as a string; length = 30). Therefore, the specfile would look like the following:
   integer,2,RandNum
   string,2,HexNum
   string,30,Stars
				
Notice that the column names in the specfile are the same names that are used in the user-defined type in the ISAM program below (ISAM.BAS). For this example, you should call the specfile DATAFILE.SPC.

Now we will convert the file to an ISAM file. First exit VBDOS.EXE or QBX.EXE and load the PROISAMD TSR program (the Btrieve TSR program should already be loaded.) After you have loaded PROISAMD, type the following command:

ISAMCVT /B datafile.btr table datafile.mdb datafile.spc

This command line tells ISAMCVT that it will be converting the Btrieve file DATAFILE.BTR to the ISAM file DATAFILE.MDB. ISAMCVT will put all the records into a table called "table" and will use the specfile DATAFILE.SPC.

After it is started, ISAMCVT should print its copyright notice and then print the following messages:
   ISAMCVT: Database 'datafile.mdb' not found.  Creating ...
   ISAMCVT: There's 2 index(s).
   ISAMCVT: Index Position       Length         Unique
   ISAMCVT:    1      1             2              0

   ISAMCVT: Index Sample:  G
   ISAMCVT: Enter the column names for the Index (Up to 255 characters):
				
At this point, ISAMCVT wants you to enter the names of the columns that this index is based on. For this example, we will use RandNum for a primary key and HexNum for a secondary. Type the following:

...characters): RandNum,HexNum

Notice that no spaces were typed. After processing this information, ISAMCVT will prompt you with the following message:
ISAMCVT: Enter a name for the Index (Up to 30 characters):
ISAMCVT is now asking for a name for the index. Type RandIndex and press the ENTER key. Next, ISAMCVT will ask for the column names and name of the second index. For that index, enter HexNum for the column names and "HexIndex" for the index name.

When ISAMCVT is finished copying all the records into the new ISAM file, it will return the following message:
ISAMCVT: Conversion Finished
At this point, the conversion is done. The second program below (ISAM.BAS) can be used to verify that the data was transferred. ISAM.BAS will print the records first sorted on the random number field, and then sorted on the hex number field (in descending order.)
 2 07*******                             (The ISAM file indexed on
 29 04****                                the RandNum key.)
 31 05*****
 54 02**
 58 03***
 71 01*
 71 0A**********
 77 08********
 78 06******
 82 09*********

 71 0A**********                        [The ISAM file indexed on the
 82 09*********                          HexNum key (in descending
 77 08********                           order).]
 2 07*******
 78 06******
 31 05*****
 29 04****
 58 03***
 54 02**
 71 01*
				

BTRIEVE.BAS

' To run this program in the VBDOS.EXE or QBX.EXE environment, you
' must first create a Quick library containing the BTRVFAR subprogram.
' You must also load the Btrieve TSR program; refer to your Btrieve
' documentation for details on how to do this.
DEFINT A-Z
duplicates = 1                          ' Constants for key flags.
modifiable = 2
segmented = 16
descend = 64
exttype = 256
binteger = 1
bstring = 0
bzstring = 11
OPEN "\dev\nul" FOR RANDOM AS #1
FIELD #1, 2 AS recl$, 2 AS pgsz$, 2 AS nkey$, 4 AS nrec$,_
          2 AS varl$, 2 AS res$, 2 AS prealloc$
FIELD #1, 16 AS dummy1$, 2 AS pos1$, 2 AS len1$, 2 AS flg1$,_
          4 AS cnt1$, 1 AS keyt1$, 5 AS res1$
FIELD #1, 32 AS dummy2$, 2 AS pos2$, 2 AS len2$, 2 AS flg2$,_
          4 AS cnt2$, 1 AS keyt2$, 5 AS res2$
FIELD #1, 48 AS dummy3$, 2 AS pos3$, 2 AS len3$, 2 AS flg3$,_
          4 AS cnt3$, 1 AS keyt3$, 6 AS res3$
LSET recl$ = MKI$(80)
LSET pgsz$ = MKI$(1024)
LSET nkey$ = MKI$(2)
LSET varl$ = MKI$(0)

LSET pos1$ = MKI$(1)        ' Key 1  (integer, allows duplicates).
LSET len1$ = MKI$(2)
LSET flg1$ = MKI$(duplicates + exttype)
LSET keyt1$ = MKI$(binteger)

LSET pos2$ = MKI$(3)        ' Key 2  (string * 2, unique).
LSET len2$ = MKI$(2)
LSET flg2$ = MKI$(modifiable + segmented + exttype + descend)
LSET keyt2$ = MKI$(bstring)

LSET pos3$ = MKI$(5)        ' Key 3  (string * 30, unique).
LSET len3$ = MKI$(30)
LSET flg3$ = MKI$(modifiable + exttype)
LSET keyt$ = MKI$(bzstring)

op = 14                     ' Create Btrieve file DATAFILE.BTR.
buflen = 64
filename$ = "datafile.btr"
posblk$ = SPACE$(128)
CALL btrvfar(op, status, posblk$, SADD(recl$), SSEG(recl$), buflen,_
             filename$, keynumber)
IF status <> 0 THEN PRINT "create ="; status: STOP

op = 0                                  ' Open file.
FIELD #1, 2 AS int$, 2 AS s1$, 30 AS s2$
CALL btrvfar(op, status, posblk$, SADD(int$), SSEG(int$), buflen,_
             filename$, keynumber)
IF status <> 0 THEN PRINT "open ="; status: STOP

FOR i = 1 TO 10                         ' Insert data into database.
   LSET int$ = MKI$(INT(RND(1) * 100) + 1)
   LSET s1$ = RIGHT$("0" + HEX$(i), 2)
   LSET s2$ = STRING$(i, "*")
   PRINT CVI(int$); s1$; s2$
   op = 2
   keyselect = 0
   keyval$ = SPACE$(20)
   buflen = 80
   CALL btrvfar(op, status, posblk$, SADD(int$), SSEG(int$), buflen,_
                keyval$,keyselect)
   IF status <> 0 THEN PRINT "insert ("; i; ") ="; status: STOP
NEXT i

PRINT
op = 12                         ' Get and print the first record.
keyselect = 0
CALL btrvfar(op, status, posblk$, SADD(int$), SSEG(int$), buflen,_
             keyval$, keyselect)
IF status <> 0 THEN PRINT "get first ="; status: STOP
PRINT CVI(int$); s1$; s2$

FOR i = 2 TO 10               ' Get and print the rest of the records.
   op = 6
   CALL btrvfar(op, status, posblk$, SADD(int$), SSEG(int$), buflen,_
                keyval$, keyselect)
   IF status <> 0 THEN PRINT "get next ("; i; ") ="; status: STOP
   PRINT CVI(int$); s1$; s2$
NEXT i

op = 1                                  ' Close file.
CALL btrvfar(op, status, posblk$, SADD(int$), SSEG(int$), buflen,_
             keyval$, keyselect)
IF status <> 0 THEN PRINT "close ="; status: STOP
CLOSE #1

ISAM.BAS
--------

' The PROISAMD TSR program must be loaded before running this program
' in the VBDOS.EXE or QBX.EXE environment.
TYPE rec                 ' Type definition corresponding to specfile.
   RandNum AS INTEGER
   HexNum AS STRING * 2
   Stars AS STRING * 30
END TYPE
DIM v AS rec

OPEN "datafile.mdb" FOR ISAM rec "table" AS #1
SETINDEX #1, "RandIndex"     ' Print data based on the random-number
MOVEFIRST #1                 ' field.
FOR i = 1 TO 10
   RETRIEVE #1, v
   PRINT v.RandNum; v.HexNum; v.Stars
   MOVENEXT #1
NEXT i
PRINT                       ' Print data based on the hex-number
SETINDEX #1, "HexIndex"     ' key field (in descending order).
MOVELAST #1
FOR i = 1 TO 10
   RETRIEVE #1, v
   PRINT v.RandNum; v.HexNum; v.Stars
   MOVEPREVIOUS #1
NEXT i
CLOSE #1
				

Modification Type:MinorLast Reviewed:8/16/2005
Keywords:KB69849