home *** CD-ROM | disk | FTP | other *** search
- PROGRAM Crunch1; { (c) 1993 John C. Leon last updated 6/9/93 }
-
- {
- Will take any standard, fixed-length or variable length, Btrieve file and
- produce a clone with the same file structure, then transfer records from
- the source to the target file.
-
- There is a limit on variable length files of a total of 32767 bytes (the
- value of CONST MaxDBufferLength) for the entire (fixed and variable portions)
- data buffer/record.
-
- The purpose of the program is to remove dead space in the source file left
- over from deletions in the source.
-
- Supplemental indexes are retained as supplemental indexes in the target.
-
- If the source file has an owner name, it must be supplied as the third
- command-line parameter, in order to read the source file, but the target
- file will NOT have an owner name.
-
- This program uses only standard Btrieve 5.10 calls. In CRUNCH2.PAS, we
- use "step next extended" and "insert extended" calls to accomplish the same
- thing as this program.
-
- This program illustrates the use of the BSized object, and has the
- interesting twist of using the source file's data buffer as the data buffer
- for the target file's BSized object.
- }
-
-
- {$IFDEF production} {$D-,R-,L-,S-} {$ENDIF}
-
- USES
- Crt, DOS, BTP;
-
- CONST
- BufferLength : word = MaxFixedRecLength;
- NOTICE1 = 'Crunch1 (C) 1993 John C. Leon. All Rights Reserved.';
- NOTICE2 = '----------------------------------------------------------------------';
-
- VAR
- OrgName, CopyName : string[79];
- OrgFile, CopyFile : PBSized;
- OwnerName : string;
- Counter, x, y : longint;
-
- procedure PrintNotices;
- begin
- writeln(NOTICE1);
- writeln(NOTICE2);
- writeln;
- end;
-
- procedure VerifyTargetOverWrite;
- var
- Response: string;
- DirInfo : SearchRec;
- begin
- findfirst(CopyName, archive, DirInfo);
- if doserror = 0 then
- begin
- writeln;
- write('Target file ', CopyName, ' exists. Overwrite? (Y/N): ');
- readln(Response);
- Response[1] := upcase(Response[1]);
- if Response[1] = 'N' then
- begin
- dispose(OrgFile, Done);
- halt(5);
- end;
- if Response[1] <> 'Y' then
- begin
- writeln;
- writeln('Invalid response ... program aborted.');
- dispose(OrgFile, Done);
- halt(6);
- end;
- end;
- end;
-
-
- (* Begin MAIN program code *)
- (* ------------------------------------------------------------------------ *)
- BEGIN
-
- if not IsBtrieveLoaded then
- begin
- writeln;
- writeln('Please load Btrieve before running this program.');
- writeln;
- halt(1);
- end;
-
- clrscr;
- PrintNotices;
-
- {If user asked for help, or didn't pass two filenames, give help and exit.}
- if (paramstr(1) = '?') or (paramstr(1) = '/?') or (paramstr(1) = '-?') or
- (paramcount < 2) then
- begin
- writeln;
- writeln('USAGE: CRUNCH1 sourcefile targetfile [owner]');
- writeln;
- writeln('This program will create the target file, duplicating the original');
- writeln('file''s structure exactly. Supplemental indexes, if any, and');
- writeln('an alternate collating sequence, if any, will be duplicated in');
- writeln('the target file.');
- writeln;
- writeln('If the source file has an owner name, specify the owner name as');
- writeln('the third command line parameter. In no event will the target');
- writeln('file be created with an owner name.');
- writeln;
- writeln('After creating the target file, all records will be copied from');
- writeln('the source file to the target.');
- writeln;
- writeln('Variable length files with record lengths to 32,767 are supported');
- halt(2);
- end;
-
- OrgName := paramstr(1); CopyName := paramstr(2);
- for Counter := 1 to length(OrgName) do
- OrgName[Counter] := upcase(OrgName[Counter]);
- for Counter := 1 to length(CopyName) do
- CopyName[Counter] := upcase(CopyName[Counter]);
- OwnerName := '';
- if paramcount >= 3 then
- OwnerName := paramstr(3);
-
- { Open original file in read only mode }
- OrgFile := new(PBSized, Init(OrgName, ReadOnly, OwnerName, BufferLength));
-
- if BStatus <> Zero then
- begin
- writeln('Error opening ', OrgName, '. Program aborted.');
- dispose(OrgFile, Done);
- halt(3);
- end;
-
- if OrgFile^.NumRecs = 0 then {don't proceed if empty file}
- begin
- writeln('No records in ', OrgName, '. Program aborted.');
- OrgFile^.Close;
- dispose(OrgFile, Done);
- halt(4);
- end;
-
- {If target file exists, get confirmation before overwriting. Program will be
- aborted if target exists and user elects to abort.}
-
- VerifyTargetOverWrite;
-
- if (OrgFile^.Specs.FileFlags and VarLength) = VarLength then
- begin
- BufferLength := MaxDBufferLength;
- OrgFile^.Close;
- dispose(OrgFile, Done);
- OrgFile := new(PBSized, Init(OrgName, ReadOnly, OwnerName, BufferLength));
- end;
-
- {Create copy of original, using precisely the same specs, but do not use
- any owner name the source file may have used.}
-
- BStatus := CloneFile(OrgName, CopyName, Retain, '');
- if BStatus = Zero then
- writeln(CopyName, ' created successfully.')
- else
- begin
- writeln;
- writeln('Error creating ', CopyName, '. Status = ', BStatus, '.');
- writeln('Program aborted.');
- writeln;
- dispose(OrgFile, Done);
- halt(7);
- end;
-
- {Open new copy of file in accelerated mode.}
- CopyFile := new(PBSized, Init(CopyName, Accel, '', BufferLength));
-
- writeln;
- writeln('Number of records in ', OrgName, ': ', OrgFile^.NumRecs);
- write('Number of records inserted: ');
- x := wherex;
- y := wherey;
-
- freemem(CopyFile^.DBuffer, CopyFile^.DBufferSize);
- CopyFile^.DBuffer := OrgFile^.DBuffer;
-
- {Main loop...read a record, write a record.}
- for Counter:= 1 to OrgFile^.NumRecs do
- begin
- OrgFile^.BT(BStepNext, Zero);
- CopyFile^.BT(BInsert, Zero);
- if (Counter MOD 5) = 0 then
- begin
- gotoxy(x, y);
- write(Counter);
- end;
- end;
- if (Counter MOD 5) <> 0 then
- write(Counter);
- writeln;
- writeln('DONE...');
-
- BStatus := OrgFile^.Close;
- BStatus := CopyFile^.Close;
-
- dispose(OrgFile, Done);
- CopyFile^.DBuffer := nil; {As we're using OrgFile's pointer, which became
- undefined when OrgFile was disposed, this pointer
- is now undefined. If we don't set the undefined
- pointer to nil, CopyFile's destructor will try to
- free it's memory and kill prog w/runtime error.}
- dispose(CopyFile, Done);
-
- END.
-