Database Search
- Jeff Barnes
- Posts: 912
- Joined: Sun Oct 09, 2005 1:05 pm
- Location: Ontario, Canada
- Contact:
Database Search
Hi,
Is there a fast way to search all fields in a database for some text.
Thanks,
Jeff
Is there a fast way to search all fields in a database for some text.
Thanks,
Jeff
-
- Posts: 310
- Joined: Mon Oct 10, 2005 5:10 am
Search
Jeff
There is a third party function called wildseek - never
used it though - I have used the rat() and at() functions to find part
of names in a cash record database, but this checks every record ,
unless you can set a scope on a subset of records.
Cheers
Colin
There is a third party function called wildseek - never
used it though - I have used the rat() and at() functions to find part
of names in a cash record database, but this checks every record ,
unless you can set a scope on a subset of records.
Cheers
Colin
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Jeff,
Some years ago we helped a company to test several third party tools for such purpouse and finally implemented our own solution to make the fastest search on all fields of a DBF.
We found with great surprise that the solution was to open the DBF as a standard file with FOpen(), read a bunch of bytes in memory and perform a simple At() to locate a string. Once found, you substract the DBF header length, then divide the offset by the record size and you get the record number. At() is an extremelly fast function as it is directly performed by the processor.
These days that we use 32 bits flat memory, I guess there is no need to use a bunch of bytes, so the entire DBF may be loaded in memory doing a MemoRead() of the DBF file, or several bunchs if it is too large, so the code may get simpler.
We compared this way with other available third party tools, and we found that ours was the fastest one
Its worth to try it.
Some years ago we helped a company to test several third party tools for such purpouse and finally implemented our own solution to make the fastest search on all fields of a DBF.
We found with great surprise that the solution was to open the DBF as a standard file with FOpen(), read a bunch of bytes in memory and perform a simple At() to locate a string. Once found, you substract the DBF header length, then divide the offset by the record size and you get the record number. At() is an extremelly fast function as it is directly performed by the processor.
These days that we use 32 bits flat memory, I guess there is no need to use a bunch of bytes, so the entire DBF may be loaded in memory doing a MemoRead() of the DBF file, or several bunchs if it is too large, so the code may get simpler.
We compared this way with other available third party tools, and we found that ours was the fastest one
Its worth to try it.
- Eugeniusz Owsiak
- Posts: 60
- Joined: Fri Oct 07, 2005 5:38 am
- Location: Poland
- Jeff Barnes
- Posts: 912
- Joined: Sun Oct 09, 2005 1:05 pm
- Location: Ontario, Canada
- Contact:
Antonio,
I tried your idea but I have 2 problems...
1. It returns the record number -1
example: I know the record is #5 but it return #4
2. I need to search for ALL occurences of "sometext". At() will only find the first (and RAt() the last)
Can you think of any other way of doing it?
Thanks,
Jeff
P.S. This is the Code I tried:
Function SearchFile( cDBF, cAlias )
Local cSearch := Space(20), nLocation, cData
if ! MsgGet("Search...","Enter Search String ",@cSearch)
Return nil
endif
SELECT &cAlias
cData := MemoRead( cDBF )
if Len(cData ) < 1
MsgInfo("Not Data to Search","File Error")
Return Nil
endif
nLocation := (AT( cSearch, cData ) - Header() ) / RecSize()
if nLocation < 1
Exit
else
MsgInfo("Record: "+str(nLocation ))
endif
Return Nil
I tried your idea but I have 2 problems...
1. It returns the record number -1
example: I know the record is #5 but it return #4
2. I need to search for ALL occurences of "sometext". At() will only find the first (and RAt() the last)
Can you think of any other way of doing it?
Thanks,
Jeff
P.S. This is the Code I tried:
Function SearchFile( cDBF, cAlias )
Local cSearch := Space(20), nLocation, cData
if ! MsgGet("Search...","Enter Search String ",@cSearch)
Return nil
endif
SELECT &cAlias
cData := MemoRead( cDBF )
if Len(cData ) < 1
MsgInfo("Not Data to Search","File Error")
Return Nil
endif
nLocation := (AT( cSearch, cData ) - Header() ) / RecSize()
if nLocation < 1
Exit
else
MsgInfo("Record: "+str(nLocation ))
endif
Return Nil
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Jeff,
> 1. It returns the record number -1
Add 1 to it
> 2. I need to search for ALL occurences of "sometext". At() will only find the first (and RAt() the last)
Modify your function, so when you find the text, then you modify the cData:
cData = SubStr( cData, nLocation + Len( cSearch ) )
and then perform At() again until there are no more occurrences. Store the previous nLocation on a variable to properly calculate the offset.
> 1. It returns the record number -1
Add 1 to it
> 2. I need to search for ALL occurences of "sometext". At() will only find the first (and RAt() the last)
Modify your function, so when you find the text, then you modify the cData:
cData = SubStr( cData, nLocation + Len( cSearch ) )
and then perform At() again until there are no more occurrences. Store the previous nLocation on a variable to properly calculate the offset.
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Jeff,
Both Harbour/xHarbour lets you specify a third parameter when calling At() to select the starting offset into the text.
This is a better way so you don't have to call SubStr() which manages a lot of memory for copying the previous string into the new one, so it will result into an even faster function
At( cSearch, cData, nOffset )
Both Harbour/xHarbour lets you specify a third parameter when calling At() to select the starting offset into the text.
This is a better way so you don't have to call SubStr() which manages a lot of memory for copying the previous string into the new one, so it will result into an even faster function
At( cSearch, cData, nOffset )
- Jeff Barnes
- Posts: 912
- Joined: Sun Oct 09, 2005 1:05 pm
- Location: Ontario, Canada
- Contact:
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
-
- Posts: 22
- Joined: Fri Nov 04, 2005 9:05 pm
- Location: LIEGE Belgium
searching records
In other to show only the records you have found,
place the record number in a data base (in place of an array) and after that use the instruction SET RELATION TO
place the record number in a data base (in place of an array) and after that use the instruction SET RELATION TO
Re: Database Search
Amigo: si no has solucionado todavia tu problema enviame un mensajea.
RODOLFO SILVA
email: sildata@cantv.net
RODOLFO SILVA
email: sildata@cantv.net