Gossamer Forum
Home : Products : DBMan : Customization :

Entering FP numbers in db and controlling range of values accepted

Quote Reply
Entering FP numbers in db and controlling range of values accepted
 
Hi.

First off, I have to say that JPDeni's excellent resources have helped me out immensely. Got the basics for my database up and running on my system pretty much on my own, just by reading the docs and JPDeni's page.

I have a question now though.

My database is for my car club. I want to add fields for people to record their 1/4 mile times (i.e. drag racing) in. I would like to know if its possible to set up fields to store a floating point number, and constrain the range of values.

More specifically, I have 3 fields and would like to constrain the values thusly:

1/4 ET : 10.000 to 19.999
1/4 mph: 70.000 to 129.999
60' time: 1.500 to 2.999


Thanks for any info,

juan



Quote Reply
Re: Entering FP numbers in db and controlling range of values accepted In reply to
Oh, I'm so glad my site helped you! Smile

I don't think there's a problem with floating point numbers. I know that people have used DBMan as a store inventory, using prices with decimals in them. Be sure to set the field type to "numer" for the fields that will have the numbers in them. (But you already knew that, didn't you? Smile )

I don't believe there is a regular expression you can put into the field definitions to constrain the values to a specific range. You can, however, edit sub validate_record to do what you want.

Change

Code:
foreach $col (@db_cols) {
if ($in{$col} =~ /^\s*$/) { # entry is null or only whitespace
($db_not_null{$col}) and # entry is not allowed to be null.
push(@input_err, "$col (Can not be left blank)"); # so let's add it as an error
}
else { # else entry is not null.
($db_valid_types{$col} && !($in{$col} =~ /$db_valid_types{$col}/)) and
push(@input_err, "$col (Invalid format)"); # but has failed validation.
}
(length($in{$col}) > $db_lengths{$col}) and
push (@input_err, "$col (Too long. Max length: $db_lengths{$col})");
if ($db_sort{$col} eq "date") {
push (@input_err, "$col (Invalid date format)") unless &date_to_unix($in{$col});
}
}

to

Code:
foreach $col (@db_cols) {
if ($in{$col} =~ /^\s*$/) { # entry is null or only whitespace
($db_not_null{$col}) and # entry is not allowed to be null.
push(@input_err, "$col (Can not be left blank)"); # so let's add it as an error
}
else { # else entry is not null.
($db_valid_types{$col} && !($in{$col} =~ /$db_valid_types{$col}/)) and
push(@input_err, "$col (Invalid format)"); # but has failed validation.
(length($in{$col}) > $db_lengths{$col}) and
push (@input_err, "$col (Too long. Max length: $db_lengths{$col})");
if ($db_sort{$col} eq "date") {
push (@input_err, "$col (Invalid date format)") unless &date_to_unix($in{$col});
}
if ($col eq 'FieldName') {
($in{'FieldName'} < 10 or $in{'FieldName'} > 19.999) and
push(@input_err, "$col not within acceptable range");
}

}
}

In the bolded section above, replace FieldName with the name of your field and enter the correct upper and lower limits for the field. Repeat this same structure for each of the fields you want to constrain.

I wish there was a better way to do this, but I don't know of one.


------------------
JPD






Quote Reply
Re: Entering FP numbers in db and controlling range of values accepted In reply to
 
That worked like a charm!

You rock!


BTW, this isn't quite so important, but do you know of a way I can have the trailing zeroes added?

For example, if someone enters "89", the entry in the database would be "89.000"?

Now that I think about it, the ultimate solution would actually be to use nines instead. So if someone entered "89", the entry would actually be "89.999". Some people like to exaggerate their performance by leaving out some of the numbers, and I'd like to prevent them from doing that. If they really did get an 89 flat, then they should put in "89.000".


But I am totally happy with the current operation.

thanks,
juan
Quote Reply
Re: Entering FP numbers in db and controlling range of values accepted In reply to
Padding with 0s is easier than padding with 9s. I'm not sure how to do the latter. I'll take a look in one of my books and see what I can come up with.

Glad the code worked for you. Smile


------------------
JPD






Quote Reply
Re: Entering FP numbers in db and controlling range of values accepted In reply to
 
Hi,

I ran into a slight snag with this mod. These FP fields are not intended to be mandatory (ie not_null = 0), but putting in this condition in db.cgi seems to make it so.

if ($col eq 'QuarterET') {
($in{'QuarterET'} < 10 or $in{'QuarterET'} > 19.999) and
push(@input_err, "$col not within acceptable range");
}

I'm guess it needs some sort of "if not null, then do this check" or something (sorry - I'm not really a Perl programmer, I just play one on my website... )

Any thoughts on this one?

juan




Quote Reply
Re: Entering FP numbers in db and controlling range of values accepted In reply to
If you notice, the code for checking the values is within the part of sub validate_record that is only checked if the entry is not null. I moved around some of the original coding.

In the code I gave you, it checks to see if the field is empty--

if ($in{$col} =~ /^\s*$/) {

If it is, it checks to see if the field is allowed to be empty --

($db_not_null{$col}) and # entry is not allowed to be null.
push(@input_err, "$col (Can not be left blank)"); # so let's add it as an error

If it is not empty --

else { # else entry is not null.

it checks to see if it's all right. It checks to see if it's a valid entry, if it's too long, whether it's a date and if the date format is correct, and whether or not it is within your acceptable range. All of those checks are only made if there is something within the field.


------------------
JPD






Quote Reply
Re: Entering FP numbers in db and controlling range of values accepted In reply to
 
Hi there, JPDeni.

I guess I'm still not getting it.

The code I have in my db.cgi matches what you showed in the sample, except I found that I had to put a "}" before the "(length($in{$col}) > $db_lengths{$col}) and" line, otherwise I got an Internal Service Error.


Putting that } back in, if I leave say the Quarter ET field blank, I get the message:
"QuarterET not within acceptable range"

For any combination of leaving the FP fields blank, the error message is similar to the above, but with the appropriate fieldnames.


Let me post the code I've got. I'm probably missing something obvious...


<< from default.cfg>>

# Database Definition

%db_def = (
ID => [0, 'numer', 5, 8, 1, '', ''],
Name => [1, 'alpha', 30, 255, 1, '', ''],
Nick => [2, 'alpha', 25, 255, 0, '', ''],
City => [3, 'alpha', 25, 255, 1, '', ''],
StateProv => [4, 'alpha', 0, 40, 1, '', ''],
Email => [5, 'alpha', 30, 255, 1, '', '.+\@.+\..+'],
WebPage => [6, 'alpha', 40, 255, 0, 'http://', '^http://'],
Car => [7, 'alpha', 0, 60, 1, '', ''],
Year => [8, 'alpha', 0, 60, 1, '', ''],
Colour => [9, 'alpha', 0, 22, 0, '', ''],
Performance => [10, 'alpha', '50x2', 500, 0, '', ''],
Handling => [11, 'alpha', '50x2', 500, 0, '', ''],
Appearance => [12, 'alpha', '50x2', 500, 0, '', ''],
Audio => [13, 'alpha', '50x2', 500, 0, '', ''],
Misc => [14, 'alpha', '50x2', 500, 0, '', ''],
QuarterET => [15, 'numer', 5, 8, 0, '', ''],
QuarterMPH => [16, 'numer', 5, 8, 0, '', ''],
Quarter60 => [17, 'numer', 5, 8, 0, '', ''],
Pics => [18, 'alpha', 40, 255, 0, 'http://', '^http://'],
DateSubmit => [19, 'date', 12, 15, 1, &get_date, ''],
DateMod => [20, 'date', 12, 15, 1, &get_date, ''],
Userid => [21, 'alpha', -2, 15, 0, '', '']

);


<<from html.pl>>

print qq|
<TABLE WIDTH="450" CELLPADDING=0 CELLSPACING=0 BORDER=1 BGCOLOR="#FFFFCC">
... other field definitions...

<TR><TD ALIGN="Right" VALIGN="TOP"><$font>Quarter ET:</FONT></TD>
<TD VALIGN="TOP"> <INPUT TYPE="TEXT" NAME="QuarterET" VALUE="$rec{'QuarterET'}" SIZE="6" MAXLENGTH="6"></TD></TR>
<TR><TD ALIGN="Right" VALIGN="TOP"><$font>Quarter MPH:</FONT></TD>
<TD VALIGN="TOP"> <INPUT TYPE="TEXT" NAME="QuarterMPH" VALUE="$rec{'QuarterMPH'}" SIZE="7" MAXLENGTH="7"></TD></TR>
<TR><TD ALIGN="Right" VALIGN="TOP"><$font>Quarter 60':</FONT></TD>
<TD VALIGN="TOP"> <INPUT TYPE="TEXT" NAME="Quarter60" VALUE="$rec{'Quarter60'}" SIZE="5" MAXLENGTH="5"></TD></TR>

</TABLE>



<<from db.cgi>>

foreach $col (@db_cols) {

if ($in{$col} =~ /^\s*$/) { # entry is null or only whitespace
($db_not_null{$col}) and # entry is not allowed to be null.
push(@input_err, "$col (Can not be left blank)"); # so let's add it as an error
}
else { # else entry is not null.
($db_valid_types{$col} && !($in{$col} =~ /$db_valid_types{$col}/)) and
push(@input_err, "$col (Invalid format)"); # but has failed validation.
}
(length($in{$col}) > $db_lengths{$col}) and
push (@input_err, "$col (Too long. Max length: $db_lengths{$col})");
if ($db_sort{$col} eq "date") {
push (@input_err, "$col (Invalid date format)") unless &date_to_unix($in{$col});
}

if ($col eq 'QuarterET') {
($in{'QuarterET'} < 10 or $in{'QuarterET'} > 19.999) and
push(@input_err, "$col not within acceptable range");
}
if ($col eq 'QuarterMPH') {
($in{'QuarterMPH'} < 70 or $in{'QuarterMPH'} > 129.999) and
push(@input_err, "$col not within acceptable range");
}
if ($col eq 'Quarter60') {
($in{'Quarter60'} < 1.500 or $in{'Quarter60'} > 2.999) and
push(@input_err, "$col not within acceptable range");
}

}



I really do appreciate whatever help you can provide on this. Once I get this part working, I only need to get the new account setup part done and I'll be set to roll out the db to my members.

thanks,
juan


Quote Reply
Re: Entering FP numbers in db and controlling range of values accepted In reply to
I think you put the code in the wrong place. Here's the entire subroutine:

Code:
sub validate_record {
# --------------------------------------------------------
# Verifies that the information passed through the form and stored
# in %in matches a valid record. It checks first to see that if
# we are adding, that a duplicate ID key does not exist. It then
# checks to see that fields specified as not null are indeed not null,
# finally it checks against the reg expression given in the database
# definition.

my ($col, @input_err, $errstr, $err, $line, @lines, @data);

if ($in{'add_record'}) { # don't need to worry about duplicate key if modifying
open (DB, "<$db_file_name") or &cgierr("error in validate_records. unable to open db file: $db_file_name.\nReason: $!");
if ($db_use_flock) { flock(DB, 1); }
LINE: while (<DB> ) {
(/^#/) and next LINE;
(/^\s*$/) and next LINE;
$line = $_; chomp ($line);
@data = &split_decode($line);
if ($data[$db_key_pos] eq $in{$db_key}) {
return "duplicate key error";
}
}
close DB;
}
foreach $col (@db_cols) {
if ($in{$col} =~ /^\s*$/) { # entry is null or only whitespace
($db_not_null{$col}) and # entry is not allowed to be null.
push(@input_err, "$col (Can not be left blank)"); # so let's add it as an error
}
else { # else entry is not null.
($db_valid_types{$col} && !($in{$col} =~ /$db_valid_types{$col}/)) and
push(@input_err, "$col (Invalid format)"); # but has failed validation.
(length($in{$col}) > $db_lengths{$col}) and
push (@input_err, "$col (Too long. Max length: $db_lengths{$col})");
if ($db_sort{$col} eq "date") {
push (@input_err, "$col (Invalid date format)") unless &date_to_unix($in{$col});
}
if ($col eq 'QuarterET') {
($in{'QuarterET'} < 10 or $in{'QuarterET'} > 19.999) and
push(@input_err, "$col not within acceptable range");
}
if ($col eq 'QuarterMPH') {
($in{'QuarterMPH'} < 70 or $in{'QuarterMPH'} > 129.999) and
push(@input_err, "$col not within acceptable range");
}
if ($col eq 'Quarter60') {
($in{'Quarter60'} < 1.500 or $in{'Quarter60'} > 2.999) and
push(@input_err, "$col not within acceptable range");
}
}
}
if ($#input_err+1 > 0) { # since there are errors, let's build
foreach $err (@input_err) { # a string listing the errors
$errstr .= "<li>$err"; # and return it.
}
return "<ul>$errstr</ul>";
}
else {
return "ok"; # no errors, return ok.
}
}

------------------
JPD






Quote Reply
Re: Entering FP numbers in db and controlling range of values accepted In reply to
 
That did it! You are sooo awesome! Smile


I missed the extra closing curlie for the else block, which is why I was getting the Internal error initially, I guess.

Reminds me of my actual job. I spent two days hacking around with a fairly simple script I made in our software, trying to track down and fix errors from my poor programming logic. I'm more into design rather then execution...

Anyways, thanks again!

juan

Quote Reply
Re: Entering FP numbers in db and controlling range of values accepted In reply to
That's what my hubby keeps telling me -- that I'm awesome!! Wink

Glad I could help. There's so many times when I have bracket problems. I couldn't even begin to count them. I see them much better in the work of other people. Smile


------------------
JPD