Gossamer Forum
Home : Products : DBMan : Customization :

Help with reading a file correctly

Quote Reply
Help with reading a file correctly
Please help solve this problem. For DBMan the following subs are used to have people save their favorites records into a separate database. Saving to the database works fine.

The problem is then in reading the file (sub view_favorites) and only returning the exact record IDs saved for each user.

A sample of the favorite.db looks like:

534-jackstraw|28-Mar-2002
494-jackstraw|28-Mar-2002
269-jackstraw|28-Mar-2002
614-lchiang|28-Mar-2002
1062-oldmoney|25-Apr-2002
649-kjellkk|07-May-2002
114-omegadm|15-May-2002
6-oldmoney|15-May-2002

What is happening is on the single digit record IDs such as # 6. It will then display all records containing the number 6.

Any help on getting sub view_favorites to display the exact record IDs would be appreciated.


sub add_to_favorites {
#---------------------------------------
open (FAVE, "<$db_favorites") or &cgierr("error in add_to_favorites. Unable to open favorites file: $db_favorites.\nReason: $!");
if ($db_use_flock) { flock(FAVE, 1); }
LINE: while (<FAVE> ) {
(/^#/) and next LINE;
(/^\s*$/) and next LINE;
$line = $_; chomp ($line);
@data = &split_decode($line);
if ($data[0] eq "$in{$db_key}-$db_userid") {
$message = "That listing is already in your favorites list";
}
}
close FAVE;
unless ($message) {
open (FAVE, ">>$db_favorites") or &cgierr("error in add_to_favorites. Unable to open favorites file: $db_favorites.\nReason: $!");
if ($db_use_flock) {
flock(FAVE, 2) or &cgierr("Unable to get exclusive lock on $db_favorites.\nReason: $!");
}
$date = &get_date();
print FAVE "$in{$db_key}-$db_userid|$date\n";
close FAVE; # automatically removes file lock
$message = "Listing added to favorites list";
}
&html_favorite_success($message);
}
sub view_favorites {
# --------------------------------------------------------
open (FAVE, "<$db_favorites") or &cgierr("error in view_favorites. Unable to open favorites file: $db_favorites.\nReason: $!");
if ($db_use_flock) { flock(FAVE, 1); }
@flines = <FAVE>;
close FAVE;
foreach $fline (@flines) {
@data = &split_decode($fline);
if ($data[0] =~ /(.+)-$db_userid/) {
$in{$db_key} .= "$1|";
}
}
chop $in{$db_key};
$in{'re'} = 1;
$in{'ww'} = 1;
my ($status, @hits) = &query("view");
if ($status eq "ok") {
&html_view_success(@hits);
}
else {
&html_view_failure("No favorites on file");
}
}

Unoffical DBMan FAQ

http://creativecomputingweb.com/dbman/index.shtml/
Quote Reply
Re: [LoisC] Help with reading a file correctly In reply to
Lois, there is nothing wrong with reading the DB per se, since the problem lies in $in{'ww'} never getting passed through to sub query (I was calling it sub search earlier Unimpressed).
Code:
my ($status, @hits) = &query("view");

Hope that helps some...

Last edited by:

oldmoney: May 15, 2002, 10:41 PM
Quote Reply
Re: [LoisC] Help with reading a file correctly In reply to
Use this for reading/looping/matching:

Code:
sub view_favorites {
# --------------------------------------------------------
# Read the favorites.

open (FAVE, "<$db_favorites") or &cgierr("error in view_favorites. Unable to open favorites file: $db_favorites.\nReason: $!");
flock(FAVE, 1) if $db_use_flock;
while (chomp( $_ = <FAVE> )) {
my @row = split_decode($_);
if ($row[0] =~ /^(\d+)-$db_userid/) {
$in{$db_key} .= "$1|";
last;
}
}

....the way it currently is, is very slow and will loop through the whole array even if you get a match...but it also has to read the whole file into an array first....also the (.+) in the regex probably won't match what you expect ;) ....you'd want (.+?) but (\d+) is better anyway.

I also don't understand why you have:

$in{$db_key} = "$1|";

.....and then you use:

chop $in{$db_key};

....right under it, so basically you are just getting rid of the | you just added.

Last edited by:

Paul: May 16, 2002, 2:07 AM
Quote Reply
Re: [Paul] Help with reading a file correctly In reply to
Well, you do understand that I'm not a programmer, JPDeni wrote this code awhile back I'm just trying to get it to work.

With your suggestion I changed the sub to read:

sub view_favorites {
# --------------------------------------------------------
# Read the favorites.

open (FAVE, "<$db_favorites") or &cgierr("error in view_favorites. Unable to open favorites file: $db_favorites.\nReason: $!");
flock(FAVE, 1) if $db_use_flock;
while (chomp( $_ = <FAVE> )) {
my @row = split_decode($_);
if ($row[0] =~ /^(\d+)-$db_userid/) {
$in{$db_key} .= "$1|";
last;
}
}
chop $in{$db_key};
$in{'re'} = 1;
$in{'ww'} = 1;
my ($status, @hits) = &query("view");
if ($status eq "ok") {
&html_view_success(@hits);
}
else {
&html_view_failure("No favorites on file");
}
}

What happens now is that it only returns the first record matching the favorites saved by me instead of all the favorites listed in the database under my userid.

It should return a listing of all the favorites saved in the database that match the logged in user.

Unoffical DBMan FAQ

http://creativecomputingweb.com/dbman/index.shtml/
Quote Reply
Re: [LoisC] Help with reading a file correctly In reply to
How do you build the output once you've got the matching records?

After you've looped through the file what happens in &query("view") - what is stored in @hits, $in{$db_key} doesn't seem to be used anywhere?

Inside the if ($row[0] ....) { } you could push $1 into an array to get all the ids, then use &get_record to build the output or build it straight away with %output = get_record($1);

Last edited by:

Paul: May 16, 2002, 10:44 AM
Quote Reply
Re: [Paul] Help with reading a file correctly In reply to
Paul:

I don't know how to answer your questions. All I know is the subs work fine to savea listing of favorites within the database. If the higher record IDs are saved it displays them correctly within DBMan .. making a list of all favorites saved which link to the full records.

As oldmoney stated: "$in{'ww'} never getting passed through
to sub query"

So the only problem with the original codes is that it's not recognizing the ww so that it returns only the exact record IDs (in my case for single digit numbers).

So instead of returning just record 6 for instance it returns all records IDs which contain the number 6.

Perhaps someone else can help find a solution.

Unoffical DBMan FAQ

http://creativecomputingweb.com/dbman/index.shtml/
Quote Reply
Re: [Paul] Help with reading a file correctly In reply to
Paul's code stops at the first match with a user, though the way the favs database is currently constructed is that each fav is stored as a separate record (bad idea imo).

The reason for adding the pipe delimeter after each record is to build a regex expression, such as 1|17|195|, and then chop the trailing delimeter. So these lines are needed:

Code:
$in{$db_key} .= "$1|";
chop $in{$db_key};

In Reply To:
How do you build the output once you've got the matching records?

The intent is to simply pass thru record IDs to DBMans query function and let it build its normal db views (long or short if that mod is installed).

In Reply To:
you could push $1 into an array to get all the ids, then use &get_record to build the output or build it straight away with %output = get_record($1);

That seems it could work, effectively creating a new "view" for your favs. Or you could take the lazy man's approach like I did, build your regex link, and redirect to that link, like so...

Code:
print "Location: $db_script_url?db=$in{db}&uid=$db_uid&$db_key=$in{$db_key}&re=1&ww=1&mh=8&view_records=Search\n\n";

Whole words gets picked up on the redirect, though I still don't know why it gets ignored when calling sub query directly. Oh well... Crazy

Last edited by:

oldmoney: May 16, 2002, 11:02 AM
Quote Reply
Add to Favorites In reply to
JPDeni:

Noboby ever came up with a solution to a problem with Favorites mod.

The problem is then in reading the file (sub view_favorites) and only returning the exact record IDs saved for each user.

What is happening is on the single digit record IDs such as # 6. It will then display all records containing the number 6.

I'm wondering if you could come up with a solution as I would love to be able to add this feature back into some of my databases.

Original mod:

Add to favorites... (sub add_to_favorites)
==============================
Thread: http://gossamer-threads.com/p/000827
Subject: Add to favorites...
JFrost - 27-Aug-99
---------------------------------------------------------
JPDeni:

This is what I've come up with. I couldn't figure out how to go back to the search list, though. Sorry.

In your .cfg file, add the following code:

$db_favorites = $db_script_path . "/favorite.db"; # add to favorites

Create a blank file -- favorite.db -- in your directory. chmod to 666.

In db.cgi, with the other "elsif" statements, add code:

elsif ($in{'add_favorites'}) { if ($per_view) { &add_to_favorites; } else { &html_unauth; } } # add to favorites
elsif ($in{'view_favorites'}) { if ($per_view) { &view_favorites; } else { &html_unauth; } } # add to favorites

In db.cgi, add the following subroutines code:

sub add_to_favorites {
#---------------------------------------
open (FAVE, "<$db_favorites") or &cgierr("error in add_to_favorites. Unable to open favorites file: $db_favorites.\nReason: $!");
if ($db_use_flock) { flock(FAVE, 1); }
LINE: while (<FAVE> ) {
(/^#/) and next LINE;
(/^\s*$/) and next LINE;
$line = $_; chomp ($line);
@data = &split_decode($line);
if ($data[0] eq "$in{$db_key}-$db_userid") {
$message = "That listing is already in your favorites list";
}
}
close FAVE;
unless ($message) {
open (FAVE, ">>$db_favorites") or &cgierr("error in add_to_favorites. Unable to open favorites file: $db_favorites.\nReason: $!");
if ($db_use_flock) {
flock(FAVE, 2) or &cgierr("Unable to get exclusive lock on $db_favorites.\nReason: $!");
}
$date = &get_date();
print FAVE "$in{$db_key}-$db_userid|$date\n";
close FAVE; # automatically removes file lock
$message = "Listing added to favorites list";
}
&html_favorite_success($message);
}
sub view_favorites {
# --------------------------------------------------------
open (FAVE, "<$db_favorites") or &cgierr("error in view_favorites. Unable to open favorites file: $db_favorites.\nReason: $!");
if ($db_use_flock) { flock(FAVE, 1); }
@flines = <FAVE>;
close FAVE;
foreach $fline (@flines) {
@data = &split_decode($fline);
if ($data[0] =~ /(.+)-$db_userid/) {
$in{$db_key} .= "$1|";
}
}
chop $in{$db_key};
$in{'re'} = 1;
$in{'ww'} = 1;
my ($status, @hits) = &query("view");
if ($status eq "ok") {
&html_view_success(@hits);
}
else {
&html_view_failure("No favorites on file");
}
}

In html.pl, sub footer, add code:

print qq!| <A HREF="$db_script_link_url&view_favorites=1">View Favorites</A> ! if ($per_view);
or
print qq!| <A HREF="$db_script_link_url&view_favorites=1">View Favorites</A> ! unless ($db_userid ne "default");


In html.pl, add the following subroutine code:

sub html_favorite_success {
# --------------------------------------------------------
# This page let's the user know that the records were successfully added.
my $message = shift;
$page_title = "Favorite added";
&html_page_top;

print qq| <$font><B>$message</B><P>Please use the back button on your browser to return to your search results.</font><P> |;

&html_footer;
&html_page_bottom;
}

In sub html_record, include a link code:

[ <A HREF="$db_script_link_url&$db_key=$rec{$db_key}&add_favorites=1">Save as Favorite</A> ]

The mod writes to a small database, which has only two fields -- the key, consisting of the $db_key value for the record and the userid the date. (You didn't say you wanted the date, but I thought I'd go ahead and put it in there.)

When the user clicks the "View Favorites" link, the script looks through the "favorites.db" for anything with the userid as part of the field. When it finds the record, it takes out the part that is not part of the userid and adds it to a search term, with a |. It then sets re=1, which causes the search to look for records whose key value is any one on the list.
------------------
JPD


OOPS! Could someone move this into the DBMan Customization forum for me please.

Unoffical DBMan FAQ

http://creativecomputingweb.com/dbman/index.shtml/

Last edited by:

LoisC: Mar 20, 2005, 9:38 AM
Quote Reply
Re: [LoisC] Add to Favorites In reply to
the following changes to view_favorites seems to fix the problem:

Code:
sub view_favorites {
# --------------------------------------------------------
$in{$db_key} = '^(';
open (FAVE, "<$db_favorites") or &cgierr("error in view_favorites. Unable to open favorites file: $db_favorites.\nReason: $!");
if ($db_use_flock) { flock(FAVE, 1); }
@flines = <FAVE>;
close FAVE;
foreach $fline (@flines) {
@data = &split_decode($fline);
if ($data[0] =~ /(.+)-$db_userid/) {
$in{$db_key} .= "$1|";
}
}
chop $in{$db_key};
$in{$db_key} .= ')$';
$in{'re'} = 1;
$in{'ww'} = 1;
my ($status, @hits) = &query("view");
if ($status eq "ok") {
&html_view_success(@hits);
}
else {
&html_view_failure("No favorites on file");
}
}

Philip
------------------
Limecat is not pleased.
Quote Reply
Re: [fuzzy logic] Add to Favorites In reply to
Thanks I'll give it a try :)

Unoffical DBMan FAQ

http://creativecomputingweb.com/dbman/index.shtml/
Quote Reply
Re: [LoisC] Add to Favorites In reply to
Philip:

I can't thank you enough .. it works perfectly!!!

Now people can once again use this feature in the DBMan FAQ and save records for future viewing.

I'm so glad I brought this topic up again so a solution could be found.

Thanks again,

Lois

Unoffical DBMan FAQ

http://creativecomputingweb.com/dbman/index.shtml/
Quote Reply
Re: [LoisC] Add to Favorites In reply to
Thanks, I think I looked over and fiddled with that code for an hour before I finally realized how the query was working... once I figured out what was going on, it was just a simple hack to force DBMan's regex testing to match whole strings.

Philip
------------------
Limecat is not pleased.

Last edited by:

fuzzy logic: Mar 22, 2005, 9:01 PM