table.PACK Function

Syntax

V Pack()

Description

Removes all the records that are marked for deletion.

Discussion

You pack a table if you have deleted records that you want to permanently remove. The <TBL>.PACK() method packs a table, referenced by the object pointer, <TBL>. Packing a table reclaims the space taken up by deleted records and rebuilds indexes. When you delete a record, the record is not physically removed from the table - the record is merely 'marked' as a deleted record. Only when the table is packed, are the records that are 'marked' as deleted physically removed. If you have not yet packed a table, previously deleted records can be undeleted. This can be done through the user interface (right click on the table and select Utilities), or through Xbasic (see example below). After you have packed a table, a record's physical record number might change. For example, if you have four records in a table and you delete record number 3, the table will have 3 records, but the physical record number of the last record will still be 4. However, after you pack the table, the record number of the last record will now be 3. Because packing a table will potentially change a record's physical record number, using record number as the 'primary key' for a table is not advisable. When you fetch records in a table using the <tbl>.fetch_next() and <tbl>.fetch_prev() methods, records marked for deletion are automatically skipped. However, you can use the <tbl>.fetch_goto() method to position the pointer on a deleted record (see example below). The Pack operation requires exclusive access to a table. If exclusive read/write access cannot be obtained, the <TBL>.PACK() method causes an error. Use the <TBL>.RECORDS_DELETED() method to determine if a table has any deleted records and therefore needs to be packed.

Example

Pack the current table, but first confirm the operation.

dim tbl as P
tbl = table.current()
'Compute the Message Type code
code = UI_YES_NO + UI_SECOND_BUTTON_DEFAULT + UI_QUESTION_SYMBOL
response = ui_msg_box("Pack Table","Are you sure? ", code)
if response = UI_YES_SELECTED then 'User selected Yes
    tbl.pack()
end if
'Shows how records can be undeleted before table is packed, and how deleted records are skipped
t = table.open("customer")
 ?t.recno()
 = 1
 t.fetch_next()
 ?t.recno()
 = 2
'now delete record number 2
 t.change_begin()
 t.delete()
 t.change_end(.t.)
'note that as soon as record 2 is deleted the pointer moves to record number 3 (first undeleted record)
 ?t.recno()
 = 3
 t.fetch_first()
 ?t.recno()
 = 1
'notice how record number 2 (a deleted record) is automatically skipped over
 t.fetch_next()
 ?t.recno()
 = 3
'explicitly position pointer on physical record number 2 (a deleted record)
'this is possible because the table has not yet been packed
 t.fetch_goto(2)
 ?t.is_deleted()
 = .T.
'now undelete the record (i.e. set the 'delete' marker off)
 t.change_begin()
 t.DELETED = ""
 t.change_end(.t.)
 ?t.recno()
 = 2
 ?t.is_deleted()
 = .F.
 t.fetch_first()
 ?t.recno()
 = 1
'now, when we fetch through the records, physical record number 2 is no longer skipped
 t.fetch_next()
 ?t.recno()
 = 2

See Also