Login
`
Templates, Tools and Utilities
|
||
Icetips Article
Back to article list
Search Articles
Add Comment
Printer friendly
Direct link
Par2: Pointer() and Position 1998-05-18 -- Sean Wilson The POINTER() function is probably one of the least well understood file commands in
the Clarion language, the presence of the POSITION() command with it's apparently
identical functionality does little to clear the confusion.
The problems that arise with the use of the POINTER() function, tend to arise from
differences in the implementation of this function between one file driver and another,
and the assumptions that developers make based on past experience with other file
drivers.
There are many implementation specific differences between file drivers. Whilst the
drivers are designed to behave identically (where possible) for the documented use of
a command, it is possible to write code that will work correctly with one driver but not
with another. The POINTER() command is often misused, because the values that it
returns exhibit highly implementation dependent characteristics. I will examine the
characteristics of some of the drivers before drawing a conclusion.
The Clarion File Driver
-----------------------------------
Most Clarion developers are familiar with the Clarion File Driver which formed the basis
for the specification of most of the file commands. The value returned by the Clarion
File Driver for POINTER() is the number of the record in the sequence. This means that
if POINTER(file) returns n, the next record in the file can be obtained by calling
GET(file,n+1). Similarly, if POINTER(key) returns n, the next record in the sequence
can be obtained by calling GET(key,n+1).
This behaviour is peculiar to the Clarion driver, however many developers believe that
GET(f, POINTER(f)+1) will obtain the next record, and more particularly that GET(f, 1)
will obtain the first record in the sequence.
The TopSpeed File Driver
----------------------------------------
The TopSpeed Driver returns pointers that reflect the temporal order in which records
were added to a file.
The first record added to a TopSpeed file contains control information so GET(f,1)
does not return a valid record for an applications file.
The pointer values are added in a contiguous sequence from 1..2^32, once a value
has been allocated it will never be reallocated. One consequence of this is that pointers
are completely stable, a given pointer value will refer to the same record for the lifetime
of the table, if the record is removed the pointer will always be invalid.
Another consequence of this allocation mechanism affects superfiles where records
added to different tables within a superfile take distinct values from the same sequence.
So, for example, if you add records alternately to tables A and B in the same superfile,
table A may have pointer values 3,5,7,9,... and table B may have pointer values
4,6,8,10. That is to say, POINTER() will return a given value for at most one table in
a superfile.
It is not safe to assume that with the TopSpeed File Driver, GET(f,POINTER(f)+1)
obtains the next record in a table.
The xBase File Drivers
-----------------------------------
The xBase File Drivers return pointer values that reflect the position of the record in
the tables sequence. POINTER(file) and POINTER(key) return the same value for a
given record. Because new records are appended to the end of the file, and deletions
do not reorganise the data table, pointer values are stable until the table is compressed
using PACK(). What's more, GET(f,POINTER(f)+1) will return the next record in the
file (if it exists), but may not return the subsequent record in a key sequence.
The Paradox File Driver
-------------------------------------
The Paradox File Driver returns pointer values that reflect the position of the record
within the sequence. If the table has a primary key then the records within the table
are maintained in primary key order. This means that the pointer values can be highly
unstable. The first record in the sequence has pointer value 1, if a record with a lower
primary key value is inserted that record will return a pointer value of 1. Calling
GET(f,POINTER(f)+1) will obtain the next record in the table, and may be used to get
the next record in the primary key sequence if a primary key exists.
The DOS File Driver
-------------------------------
The DOS File Driver returns pointer values that reflect the byte postion of the record
within the file. For practical reasons, it is important to be able to arithmetically change
pointer values to access records in DOS files, so GET(f,n) will return the record starting
at the nth byte.
POSITION() to the Rescue
------------------------------------------
With such a variety of implementation specific semantics for one particular function, it is
clear to see why there can be a great deal of confusion about the POINTER() function.
The POINTER() function, clearly has it's uses, however for the purists a better
alternative is the POSITION() function.
The POSITION() function offers much the same functionality as the POINTER()
function but because of it's implementation offers less scope for misuse than the
POINTER() function and is more portable between file drivers (all drivers support
POSITION()/RESET() some drivers do not support POINTER()).
One important difference, is that the POSITION() function returns a STRING, the
driver can therefore return a great deal more information which means that there is
usually much more stability associated with POSITION() values. It is not possible to
use SET() or GET() with the values returned by the POSTION() function, but identical
results can be obtained using variations with REGET(), SET(), NEXT() and PREVIOUS().
One disadvantage, is that the size of the string returned by POSITION() is
implementation dependent, and is often dependent on the sequence. However, the
size of the string is usually documented and the Paradox File Driver even provides a
property to determine at run-time the size of the string that needs to be allocated.
Conclusions
-------------------
The POINTER() function tends to cause problems as a result of confusion to do with
the wide variety of implementation specific characteristics of the return value. The
POSITION() function returns a much more opaque value that is less prone to misuse,
is intended to be portable and is supported by all drivers.
If you choose to use POINTER() in an application remember the following:
The return value may be the position in the sequence, the byte position in the file, the
temporal position in the sequence or some other representation of the record location.
The command GET(f,1) may not obtain the first record in the sequence (use SET(f);
NEXT(f) instead).
The pointer may not have arithmetic properties, i.e. GET(f,POINTER(f)+1) may not
obtain the next record (use SET(...);NEXT(f) insead).
POSITON() is more portable.
Today is November 21, 2024, 3:57 am This article has been viewed 35196 times.
|
|