Solved

Formatting DBM Records

Posted on 2004-09-03
11
453 Views
Last Modified: 2008-02-01
I need to figure my script so that when a user submits a record to a datebase (DBM) the records get formatted . I think I have that part correct. But the other part of the script deletes a product. the problem is the code# for the product gets formatted before it's saved to the databasde. Now when it's time to delete it, how can it be found if the product information is entered differently from the way it's saved in the database. For example, if the user types in203 the information gets formatted to IN203 and saved. When that same product needs to be deleted and it's entere as in203 or IN203 how can I ensure that it will be found no matter how it's entered. I hope I explain my problem clearly. My code is completed, but it's not working properly. maybe someone can look over it and see what I am doing wrong.

Here is the purpose of the script. (I am sure the experts here will understand it though)

The script is suppose to use either function based on the button clicked. If "save" is clicked the information is formatted and saved to a database, and a thankyou page displays.

The other function is called if the "delete" button is clicked. It suppose to check to see if the product is in the database and delete it and display a webpage based on the results. The problem is what I explained above. Does the information entered needs to be formatted before database is opened?

if ($button eq "Save") {
      add();
}
elsif ($button eq "Delete") {
      remove();
}
exit;

#*****user-defined functions*****
sub add {
      #declare variables
      my %candles;
      
      #open database, format and add record, close database
      tie(%candles, "SDBM_File", "candlelist", O_CREAT|O_RDWR, 0666)
            or die "Error opening candlelist. $!, stopped";
      $candles{$codes} = "$names,$prices";
      $codes =~ s/^ +//;
      $codes =~ s/ +$//;
      $codes =~ tr/a-z/A-Z/;
      $codes =~ tr/ //d;
      $names =~ s/^ +//;
      $names =~ s/ +$//;
      $names =~ tr/ //d;
      $names = uc($names);
      $prices =~ s/^ +//;
      $prices =~ s/ +$//;      
      $prices =~ tr/ //d;
      $prices =~ tr/$//d;
      untie(%candles);

      #create web page      
      print "<HTML>\n";
      print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n";
      print "<BODY>\n";
      print "<FONT SIZE=4>Thank you, the following product has been added.<BR>\n";
      print "Candle: $codes $names $prices</FONT>\n";
      print "</BODY></HTML>\n";
      } #end add

      sub remove {
      #declare variables
      my (%candles, $msg);

      #open database
      tie(%candles, "SDBM_File", "candlelist", O_RDWR, 0)
            or die "Error opening candlelist. $!, stopped";
      #determine if the product is listed
      if (exists($candles{$codes})) {
            delete($candles{$codes});
            $msg = "The candle $codes $names $prices has been removed.";
        }
      else {
      $msg = "The product you entered is not in the database";
      }
      #close database
      untie(%candles);
      
      #create web page
      print "<HTML>\n";
      print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n";
      print "<BODY>\n";      
      print "<FONT SIZE=4>$msg</FONT>\n";
      print "</BODY></HTML>\n";      
      } #end remove


 
0
Comment
Question by:reesecup999
  • 5
  • 5
11 Comments
 
LVL 18

Expert Comment

by:kandura
ID: 11977988
Hi reesecup999,

It seems to me that you have to modify the $codes in the sub "remove" in the same way as you did in the "add" before you retrieve the record.
And you should probably move the line

    $candles{$codes} = "$names,$prices";

down to after your variable modifications, to make sure the modified versions get stored in the database.

I would put the variable modification in a separate sub, so you can call it from both "add" and "delete":

    sub format_vars {
         $codes =~ s/^ +//;
         $codes =~ s/ +$//;
         $codes =~ tr/a-z/A-Z/;
         $codes =~ tr/ //d;
         $names =~ s/^ +//;
         $names =~ s/ +$//;
         $names =~ tr/ //d;
         $names = uc($names);
         $prices =~ s/^ +//;
         $prices =~ s/ +$//;    
         $prices =~ tr/ //d;
         $prices =~ tr/$//d;
    }

The part where you add to the database would then become:

     #open database, format and add record, close database
     tie(%candles, "SDBM_File", "candlelist", O_CREAT|O_RDWR, 0666)
          or die "Error opening candlelist. $!, stopped";

     format_vars();
     $candles{$codes} = "$names,$prices";

     untie(%candles);


And the part in "delete" would become:

     tie(%candles, "SDBM_File", "candlelist", O_RDWR, 0)
          or die "Error opening candlelist. $!, stopped";

     format_vars();

     #determine if the product is listed
     if (exists($candles{$codes})) {
          delete($candles{$codes});
          $msg = "The candle $codes $names $prices has been removed.";
        }
     else {
     $msg = "The product you entered is not in the database";
     }
     #close database
     untie(%candles);


HTH,
Kandura
0
 

Author Comment

by:reesecup999
ID: 11980399
Hi Kandura,

This worked for the formatting part, but now the thank you page for the add function is a blank white screen. This is probably because the information is not been added to the database. Also, even when the product is deleted I still get the page that says "this product has been deleted" when the else statement should kick, which displays "the product is not in the database"? I thought my if statemenst were correct. What else could be wrong?

0
 

Author Comment

by:reesecup999
ID: 11980404
Sorry I forgot to post the new code.

if ($button eq "Save") {
      add();
}
elsif ($button eq "Delete") {
      remove();
}
exit;

#*****user-defined functions*****
sub format_vars {
      $codes =~ s/^ +//;
      $codes =~ s/ +$//;
      $codes =~ tr/a-z/A-Z/;
      $codes =~ tr/ //d;
      $names =~ s/^ +//;
      $names =~ s/ +$//;
      $names =~ tr/ //d;
      $names = uc($names);
      $prices =~ s/^ +//;
      $prices =~ s/ +$//;      
      $prices =~ tr/ //d;
      $prices =~ tr/$//d;
}

sub add {
      #declare variables
      my %candles;
      
      #open database, format and add record, close database
      tie(%candles, "SDBM_File", "candlelist", O_CREAT|O_RDWR, 0666)
            or die "Error opening candlelist. $!, stopped";
      format_vars();
      $candles{$codes} = "$names,$prices";
      untie(%candles);

      #create web page      
      print "<HTML>\n";
      print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n";
      print "<BODY>\n";
      print "<FONT SIZE=4>Thank you, the following product has been added.<BR>\n";
      print "Candle: $codes $names $prices</FONT>\n";
      print "</BODY></HTML>\n";
      } #end add

      sub remove {
      #declare variables
      my (%candles, $msg);

      #open database
      tie(%candles, "SDBM_File", "candlelist", O_RDWR, 0)
            or die "Error opening candlelist. $!, stopped";
      format_vars();
      #determine if the product is listed
      if (exists($candles{$codes})) {
            delete($candles{$codes});
            $msg = "The candle $codes $names $prices has been removed.";
              
      }
      else {
      $msg = "The product you entered is not in the database";
      }
      #close database
      untie(%candles);
      
      #create web page
      print "<HTML>\n";
      print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n";
      print "<BODY>\n";      
      print "<FONT SIZE=4>$msg</FONT>\n";
      print "</BODY></HTML>\n";      
      } #end remove

0
 
LVL 18

Expert Comment

by:kandura
ID: 11980461
Please verify that the variables $codes, $names and $prices are defined. I was assuming that you have assigned them previously, because they appeared to be defined in the add() and remove() subs.
I merely moved your formatting code to another subroutine. If your previous version did print text at the end of the add() routine, then it should still do so now.
0
 

Author Comment

by:reesecup999
ID: 11980986
Oops, I did not include that part in my post, but yes they are all defined. The code is not working correctly except for the formatting function. What else could be the problem?
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 18

Expert Comment

by:kandura
ID: 11981665
I just tested the code we have available here, and it runs fine. Try putting some print "$codes, $names, $prices" statements at several places to see what values they have in each stage.

I'm pretty sure your problem must be in another part of your code, and I cannot help you with that without seeing it.
0
 

Author Comment

by:reesecup999
ID: 11981839
0
 
LVL 18

Expert Comment

by:kandura
ID: 11981943
That doesn't tell me anything.

What does "perl -c c09ex5.cgi" tell you? Is the syntax OK, or are there errors?

By the way, is this homework?
0
 

Author Comment

by:reesecup999
ID: 11982345
No there are no syntax errors and yeah this is an assignmenty. I am having a very hard time with Perl. I am basically on my own it seems. I am learning things as I go though. I thought I knew what I was doing with this one because it seems pretty straigh forward. So I dont; understand why its not working. If you don't feel comfortable helping me.

0
 
LVL 18

Accepted Solution

by:
kandura earned 500 total points
ID: 11982480
> If you don't feel comfortable helping me.

No, that's not it at all. It's just that the Experts-Exchange policy forbids me to do your homework for you, which I'm sure you'll understand.
As long as my answers help you on your way to figuring out your assignment yourself, we're fine.

> I am having a very hard time with Perl.

I can understand that. It's a funny language at first, since it seems to give you so much freedom compared to other languages. It tries to do what you mean, instead of forcing you into a certain coding style. But this freedom does have its price for beginners, as it makes it more difficult to find errors or mistakes. It doesn't crash with a fatal error like Java or C would do. It won't complain if you mistype a variable somewhere, it will simply treat is as empty.

> I am basically on my own it seems.

If this is part of an assignment, then surely you should receive some help in your education? Don't you have a course book that you could consult? Can't you go to your teacher for help?


It seems I should be giving you some tips on how to do basic debugging, and methods to help you pin down errors. I apologize if the rest seems trivial to you, it is always difficult to judge someone's level based on so little evidence.

The following will probably make your program break at first, but it will help you later on. I'm going to take away some of the freedom perl normally gives you, but you'll get more precise information back for it.
I'll explain three things now, because I believe they will help you for any programming language, and they are really simple to understand and remember.
    1. use "strict" mode; declare all variables prior to use
    2. use functions instead of procedures
    3. use "print" statements to debug
There are of course many more things you will learn, but this will get you started.

First thing is to turn on "strict" mode for all your scripts. Make sure your scripts start with the following lines:

    use strict;
    use warnings;
    use diagnostics;

This will force you to declare and initialize all variables before you can use them. That way you'll be able to find obvious variable misspellings and other minor problems.
When developing cgi scripts, you should also use the following lines:

    use CGI;
    use CGI::Carp 'fatalsToBrowser';

The first will give you access to all the CGI parameters, and the second will print fatal errors in your browser window instead of the server log.

Declare your variables with "my":

    my $button = '';

or

    my $button = param('Button');


Another important thing to get used to is to almost always prefer functions over procedures.
As you may know, a procedure usually doesn't take parameters, and it usually modifies variables outside its scope. All the subs in your script are procedures: they take no input or output, but they modify $codes. A function on the other hand takes parameters, acts on those, and returns its output. It should never modify anything outside its scope (if it does, then that's called a "side-effect"). This is a proper function:

    sub multiply
    {
        my($x, $y) = @_;
        return $x * $y;
    }

You use it like this:

    my $product = multiply(3,4);


The third item is very simple. Add print statements around the area where you suspect things are going wrong. Test your cgi scripts on the command line, and you will see the changes in variables as they occur. If you use the CGI module, you'll be able to pass parameters via the command line, for example:

    perl c09ex5.cgi Button=Save codes=mycode

An example of the print statements for your script could be:

    print "Button is: ", $button, "\n";
    if ($button eq "Save") {
        add();
    }
    elsif ($button eq "Delete") {
        remove();
    }

Now you know what $button contains before you take action on it.
Another good place to add print statements would be around the calls to format_vars:

    print 'Before format_vars, $codes = ', $codes, "\n";
    format_vars();  # you should convert this procedure to a function!
    print "And now it's: ", $codes, "\n";



Now my assignment to you is to put these three points into practice and use them in your script. Let me know what you find out. If you get stuck, then just ask. I'll do my best to help you along.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
Many time we need to work with multiple files all together. If its windows system then we can use some GUI based editor to accomplish our task. But what if you are on putty or have only CLI(Command Line Interface) as an option to  edit your files. I…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now