FoxPro like goto() command

184 views
Skip to first unread message

Ethan Furman

unread,
Jul 17, 2012, 6:45:12 PM7/17/12
to Python dBase
In Foxpro if you do a

GOTO 7

with deleted off and record 7 is deleted, the record pointer doesn't
move (at least in version 6).

I don't like that.

I see four other options:

0) don't move the pointer (listed for completeness)
1) go to that record anyway
2) go to the next undeleted record
3) go to the seventh undeleted record (possibly the least practical)
4) raise an exception

Any opinions?

~Ethan~

Adrian Klaver

unread,
Jul 17, 2012, 8:36:54 PM7/17/12
to python...@googlegroups.com, Ethan Furman
#4
If you don't want deleted records and the record does not exist
otherwise, then it could not be found and it is an exception. The other
options substitute another record for the one you want and I find that
unsettling. I prefer to make that decision explicitly.

>
> ~Ethan~


--
Adrian Klaver
adrian...@gmail.com


Ethan Furman

unread,
Jul 17, 2012, 10:13:43 PM7/17/12
to python...@googlegroups.com
There is also .top(), .bottom(), .first_record, .last_record,
.prev_record, .next_record, and .current_record -- but they make sense
even skipping the deleted ones... except maybe for .current_record.

I suppose if .goto() raises an exception when the target is a deleted
record, .current_record should also (could happen when the current
record is deleted, then .use_deleted is set to False, then
.current_record is accessed.

What about indexing? if table[78] is a deleted record, .use_deleted is
False, and the program tries to access table[78], should that also raise
an exception?

~Ethan~

Adrian Klaver

unread,
Jul 17, 2012, 11:30:13 PM7/17/12
to python...@googlegroups.com
Ah, more to the story. Well I guess it comes down to what you are trying
to emulate. In SQL if you ask for a record that does not exist you get
nothing i.e SELECT * FROM some_table WHERE id=some_non_existent_id. This
is sort of like option 0, nothing happens. I would say consistency
should be the aim. If it is decided trying to move a non existent
record(deleted but hidden) raises an exception than it should for all
the various ways to do that. If that seems to harsh than retain option
0. I just think on the fly substitution is not the way to go.

Ethan Furman

unread,
Jul 18, 2012, 1:04:35 PM7/18/12
to python...@googlegroups.com
Adrian Klaver wrote:
>>> On 07/17/2012 03:45 PM, Ethan Furman wrote:
>>>> In Foxpro if you do a
>>>>
>>>> GOTO 7
>>>>
>>>> with deleted off and record 7 is deleted, the record pointer doesn't
>>>> move (at least in version 6).
>>>>
>>>> I don't like that.
>>>>
>>>> I see four other options:
>>>>
>>>> 0) don't move the pointer (listed for completeness)
>>>> 1) go to that record anyway
>>>> 2) go to the next undeleted record
>>>> 3) go to the seventh undeleted record (possibly the least practical)
>>>> 4) raise an exception

> Ah, more to the story. Well I guess it comes down to what you are trying
> to emulate. In SQL if you ask for a record that does not exist you get
> nothing i.e SELECT * FROM some_table WHERE id=some_non_existent_id. This
> is sort of like option 0, nothing happens. I would say consistency
> should be the aim. If it is decided trying to move a non existent
> record(deleted but hidden) raises an exception than it should for all
> the various ways to do that. If that seems to harsh than retain option
> 0. I just think on the fly substitution is not the way to go.

I think I'll go with option 1; if one really doesn't want to deal with
deleted records, then one can create an index based on the deleted flag
which doesn't include the deleted records (can't do that in Foxpro!
that I know of, anyway ;) :

def ignore_deleted(record):
if dbf.deleted(record):
return dbf.DoNotIndex
return dbf.recno(record)

I could add a parameter to goto(), raise_if_deleted, that defaults to
True, to help the unwary be more wary... maybe down the road if it
proves necessary or convenient, or folk want it...


~Ethan~

Adrian Klaver

unread,
Jul 18, 2012, 4:13:37 PM7/18/12
to python...@googlegroups.com
Than why have .use_deleted? If a programmer does not want to use deleted
records then that should be respected by default.

>
> def ignore_deleted(record):
> if dbf.deleted(record):
> return dbf.DoNotIndex
> return dbf.recno(record)
>
> I could add a parameter to goto(), raise_if_deleted, that defaults to
> True, to help the unwary be more wary... maybe down the road if it
> proves necessary or convenient, or folk want it...
>
>
> ~Ethan~


--
Adrian Klaver
adrian...@gmail.com

Ethan Furman

unread,
Jul 18, 2012, 5:08:23 PM7/18/12
to python...@googlegroups.com
Adrian Klaver wrote:
> On 07/18/2012 10:04 AM, Ethan Furman wrote:
>>
>> I think I'll go with option 1; if one really doesn't want to deal with
>> deleted records, then one can create an index based on the deleted flag
>> which doesn't include the deleted records (can't do that in Foxpro! that
>> I know of, anyway ;) :
>
> Than why have .use_deleted? If a programmer does not want to use deleted
> records then that should be respected by default.
>

Very good point, and very good question. If I keep .use_deleted I'll
have option 4 be the default, with option 1 a possibility:


def goto(self, recno, raise_if_deleted=True):
if is_deleted(self[recno)) and raise_if_deleted:
raise DbfError(
"Record %d is deleted and use_deleted is False" % recno)
self._index = recno

But about your very good question: why have .use_deleted? Well, it went
in long before I had usable indices, so at one point it was very
necessary. Now... not so much.

I am now contemplating removing .use_deleted, and having the index
method be the one used. This has the advantages of simpler code for me,
less questions like the above (a deleted record would not be physically
present in the index created by the below code), possible speed increase
(depending on how many records in the table are deleted), plus some
others I'm sure I'll think of after I hit <Send>. ;)


>> def ignore_deleted(record):
>> if dbf.deleted(record):
>> return dbf.DoNotIndex # record will not be present in the index
>> return dbf.recno(record)

Thoughts?

~Ethan~

Adrian Klaver

unread,
Jul 19, 2012, 10:49:28 AM7/19/12
to python...@googlegroups.com
Anything that honors ignoring deleted records works for me.
Reply all
Reply to author
Forward
0 new messages