home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
nan_news
/
vol3
/
no5
/
memopack.prg
< prev
next >
Wrap
Text File
|
1989-03-01
|
9KB
|
359 lines
MemoPack.prg
* Program: MemoPack.prg
* Editor: Clayton Neff
* Version: Clipper Summer '87
* Note(s): Demonstrates DbtCrnch().
*
CLEAR
dbt_count = ADIR("*.DBT")
DECLARE dbt_array[dbt_count], dbt_size[dbt_count]
* Read in all available .DBT files.
ADIR("*.DBT", dbt_array, dbt_size)
@ 2, 24 SAY "DbtCrnch() Demonstration Program"
@ 4, 27 SAY "Written by : Clayton Neff"
@ 7, 33 TO 8 + MIN(dbt_count, 10), 47 DOUBLE
@ 19, 25 SAY "Select .DBT file to crunch."
* Use ACHOICE() to select the .DBT file to work on.
dbt_choice = 0
dbt_choice = ACHOICE(8, 34, 7 + MIN(dbt_count, 10), 46, dbt_array)
IF(dbt_choice == 0)
QUIT
ENDIF
file_name = dbt_array[dbt_choice]
start_size = dbt_size[dbt_choice]
* Strip ".DBT" from file_name and make copies.
file_name = LEFT(file_name, AT('.', file_name) - 1)
COPY FILE &file_name..DBF TO testtemp.fdb>null
COPY FILE &file_name..DBT TO testtemp.tdb>null
@ 7, 0 CLEAR TO 24, 79
@ 7, 5 SAY "Starting .DBT file size - " + LTRIM(STR(start_size))
@ 9, 5 SAY "Packing using COPY TO..."
* Pack with COPY TO.
copy_time1 = SECONDS()
USE &file_name.
COPY TO TEMP
ERASE &file_name..DBF
ERASE &file_name..DBT
RENAME TEMP.DBF TO &file_name..DBF
RENAME TEMP.DBT TO &file_name..DBT
copy_time2 = SECONDS()
ADIR("*.dbt", dbt_array, dbt_size)
dbt_choice = ASCAN(dbt_array,file_name + ".DBT")
copy_size = dbt_size[dbt_choice]
@ 10, 5 SAY STR(start_size - copy_size) + " bytes saved in ";
+ LTRIM(STR(copy_time2 - copy_time1)) + " seconds."
COPY FILE testtemp.fdb TO &file_name..DBF>null
COPY FILE testtemp.tdb TO &file_name..DBT>null
@ 12, 5 SAY "Crunching with DbtCrnch()..."
* Crunch with DbtCrnch().
crn_time1 = SECONDS()
err_num = DbtCrnch(file_name)
crn_time2 = SECONDS()
ADIR("*.dbt", dbt_array, dbt_size)
dbt_choice = ASCAN(dbt_array,file_name + ".DBT")
crn_size = dbt_size[dbt_choice]
@ 13, 5 SAY STR(start_size - crn_size) + " bytes saved in ";
+ LTRIM(STR(crn_time2 - crn_time1)) + " seconds."
@ 14, 5 SAY "The error code returned was :" + STR(err_num,2,0)
DO CASE
CASE (err_num == 0)
@ 15, 15 SAY "No error!"
CASE (err_num == 1)
@ 15, 15 SAY "Could not USE EXCLUSIVE."
CASE (err_num == 2)
@ 15, 15 SAY "No memo fields found."
CASE (err_num == 3)
@ 15, 15 SAY "Not enough disk space for copies."
CASE (err_num == 4)
@ 15, 15 SAY "Error reading file."
CASE (err_num == 5)
@ 15, 15 SAY "Error writing file."
ENDCASE
* Display comparison results.
@ 17, 5 SAY "DbtCrnch() .DBT is ";
+ STR((crn_size/copy_size)*100,6,2) + "% of COPY TO in ";
+ STR(((crn_time2-crn_time1)/(copy_time2-copy_time1))*100,6,2);
+ "% of the time."
ERASE testtemp.fdb
ERASE testtemp.tdb
@ 20, 0
QUIT
* Function: DbtCrnch()
* Note(s): Packs DBT files.
* Returns the following error codes:
*
* 1 - Could not USE EXCULSIVE.
* 2 - No memo fields found.
* 3 - Not enough diskspace for copies.
* 4 - Error reading file
* 5 - Error writing file
*
FUNCTION DbtCrnch
PARAMETERS file_name
dbf_buff = SPACE(10) && Buffer to hold pointers in DBF file.
dbt_buff = SPACE(512) && Buffer to hold data in DBT file.
* Remove extension from file name, if passed.
IF(AT('.', file_name) != 0)
file_name = LEFT(file_name,;
AT('.', file_name) - 1)
ENDIF
dbf_name = file_name + ".DBF"
dbt_name = file_name + ".DBT"
* Return error code 1 if cannot open file
* exclusively. This code is for networked
* environments. Comment this out for single
* user situations, and uncomment the USE
* statement below. NET_USE is outlined in
* Nantucket News, Volume 1 Number 4.
*
*IF(! NET_USE(file_name, .T., 5))
* RETURN(1)
*ENDIF
*
* This code is for single user environments.
* Comment this out for networked situations,
* and uncomment the NET_USE statements above.
USE (file_name)
fcnt = FCOUNT()
rcnt = RECCOUNT()
rsize = RECSIZE()
hsize = HEADER()
PRIVATE ftype[fcnt], fsize[fcnt], temp[fcnt]
fname = ""
* Load file types and sizes into arrays.
AFIELDS(fname, ftype, fsize)
USE
total = 1
num_mems = 0
* Find memo fields and thier offset in the
* record.
FOR i = 1 TO fcnt
IF ftype[i] = 'M'
num_mems = num_mems + 1
temp[num_mems] = total
ENDIF
total = total + fsize[i]
NEXT i
* Return error code 2 if no memo fields found.
IF(num_mems == 0)
RETURN(2)
ENDIF
PRIVATE mem_offset[num_mems]
ACOPY(temp, mem_offset, 1, num_mems, 1)
RELEASE temp
odbt_hndl = FOPEN(dbt_name, 18)
IF(FERROR() != 0)
RETURN(1)
ENDIF
pntr = FSEEK(odbt_hndl, 0, 2) && Get current
** DBT file size.
need_spc = (2 * pntr) + (hsize + (rsize+rcnt))
FCLOSE(odbt_hndl)
* Return error code 3 if not enough room
* on disk.
IF(DISKSPACE() <= need_spc)
RETURN(3)
ENDIF
* Make copies of the files to be packed.
COPY FILE &dbf_name. TO temp.dbf>null
COPY FILE &dbt_name. TO temp.dbt>null
* Open the copies and a new DBT file.
odbt_hndl = FOPEN("temp.dbt", 18)
IF(FERROR() != 0)
ERASE temp.dbt
ERASE temp.dbf
RETURN(1)
ENDIF
dbf_hndl = FOPEN("temp.dbf", 18)
IF(FERROR() != 0)
FCLOSE(odbt_hndl)
ERASE temp.dbt
ERASE temp.dbf
RETURN(1)
ENDIF
ndbt_hndl = FCREATE("newdbt.dbt", 0)
IF(FERROR() != 0)
FCLOSE(odbt_hndl)
FCLOSE(dbf_hndl)
ERASE temp.dbt
ERASE temp.dbf
RETURN(1)
ENDIF
* Move to the beginning of both DBT files.
* Read the first 512 byte block.
FSEEK(odbt_hndl, 0, 0)
FSEEK(ndbt_hndl, 0, 0)
IF(FREAD(odbt_hndl, @dbt_buff, 512) != 512)
FCLOSE(ndbt_hndl)
FCLOSE(odbt_hndl)
FCLOSE(dbf_hndl)
ERASE temp.dbt
ERASE temp.dbf
ERASE newdbt.dbt
RETURN(4)
ENDIF
* Calculate the next available block in
* current DBT file.
file_mems = ASC(LEFT(dbt_buff, 1))
file_mems = file_mems + ;
(256 * ASC(SUBSTR(dbt_buff, 2, 1)))
file_mems = file_mems + ;
(65536 * ASC(SUBSTR(dbt_buff, 3, 1)))
file_mems = file_mems + ;
(16777216 * ASC(SUBSTR(dbt_buff, 4, 1)))
* Write the first 512 byte block to the new
* DBT file.
IF(FWRITE(ndbt_hndl, dbt_buff, 512) != 512)
FCLOSE(ndbt_hndl)
FCLOSE(odbt_hndl)
FCLOSE(dbf_hndl)
ERASE temp.dbt
ERASE temp.dbf
ERASE newdbt.dbt
RETURN(5)
ENDIF
* Use BEGIN SEQUENCE to reduce exiting code in
* copying loop.
BEGIN SEQUENCE
sndbk = 0
buff_cntr = 1
FOR i = 1 TO rcnt
FOR j = 1 TO num_mems
* Set pointer to memo field offset.
pntr = hsize + (rsize * (i - 1)) + ;
mem_offset[j]
FSEEK(dbf_hndl, pntr, 0)
* Read 10 character pointer into DBT
* file.
IF(FREAD(dbf_hndl, @dbf_buff, 10);
!= 10)
sndbk = 4
BREAK
ENDIF
* Loop if no memo stored.
IF(VAL(dbf_buff) == 0)
LOOP
ELSE
pntr = VAL(dbf_buff) * 512
ENDIF
FSEEK(odbt_hndl, pntr, 0)
blcks = 1
DO WHILE .T. && Loop while ! EOMemo
* Read 512 characters at old memo
* location.
IF(FREAD(odbt_hndl,@dbt_buff,512);
!= 512)
IF(FSEEK(odbt_hndl,0,1) * 512);
< (file_mems - 1)
sndbk = 4
BREAK
ELSE
dbt_buff = ;
STUFF(SPACE(512), 1, ;
LEN(dbt_buff), dbt_buff)
ENDIF
ENDIF
* Write 512 characters at new memo
* location.
IF(FWRITE(ndbt_hndl,dbt_buff,512);
!= 512)
sndbk = 5
BREAK
ENDIF
IF(AT(CHR(26), dbt_buff) == 0)
blcks = blcks + 1
ELSE
EXIT
ENDIF
ENDDO
* Write new 10 character pointer into
* DBT file.
FSEEK(dbf_hndl, -10, 1)
dbf_buff = STR(buff_cntr, 10, 0)
IF(FWRITE(dbf_hndl, dbf_buff, 10);
!= 10)
sndbk = 5
BREAK
ENDIF
buff_cntr = buff_cntr + blcks
NEXT j
NEXT i
END
FCLOSE(dbf_hndl)
FCLOSE(odbt_hndl)
* Calculate string for new next memo block.
ncnt4 = INT(buff_cntr / 16777216)
buff_cntr = buff_cntr - (ncnt4 * 16777216)
ncnt3 = INT(buff_cntr / 65536)
buff_cntr = buff_cntr - (ncnt3 * 65536)
ncnt2 = INT(buff_cntr / 256)
ncnt1 = buff_cntr - (ncnt2 * 256)
dbt_buff = CHR(ncnt1) + CHR(ncnt2) + ;
CHR(ncnt3) + CHR(ncnt4)
* Move to beginning of new DBT and write next
* block string.
FSEEK(ndbt_hndl, 0, 0)
IF(FWRITE(ndbt_hndl, dbt_buff, 4) != 4)
sndbk = 5
ENDIF
FCLOSE(ndbt_hndl)
IF(sndbk == 0) && Got through with no
** errors.
ERASE &dbt_name. && Delete old DBT file.
ERASE &dbf_name. && Delete old DBF file.
ERASE temp.dbt && Delete old DBT file
** copy.
* Rename new DBT file.
RENAME newdbt.dbt TO &dbt_name.
* Rename new DBF file.
RENAME temp.dbf TO &dbf_name.
ELSE
ERASE temp.dbt && Delete working copy
** of DBT file.
ERASE temp.dbf && Delete working copy
** of DBF file.
ERASE newdbt.dbt && Delete new copy of DBT
** file.
ENDIF
RETURN(sndbk)