I can see how they could be if an enduser were prompted for them, but that's not how I intend to populate them.
Proverbially the road to Hell is paved with good intentions. The trouble is that it becomes harder and harder to keep track of all the possible routes through your code as it grows and the chances, however slight, of allowing external input to the variables can exist.
At the very least you should sanitise these variables as close to their point of use as possible, ie: within the subroutine. So, something like this:
sub insert_unique( $table, $column, $value ) {
state %sths;
if ( !exists $sths{$table} ) {
die "Bad table '$table'" unless $table =~ /^[a-z0-9_]+$/;
die "Bad column '$column'" unless $column =~ /^[a-z0-9_]+$/;
Better, use Carp::confess instead of die. Better still, use a hash of acceptable tables to further nail things down:
sub insert_unique( $table, $column, $value ) {
use Carp;
state %sths;
state %good_table = map { $_ => 1 } qw/foo bar baz/;
if ( !exists $sths{$table} ) {
confess "Bad table '$table'" unless $good_table{$table};
By doing this, and the same for $column, you are limiting the ability of an external agent (or your own fat fingers) to operate on parts of the database to which there should not be access.
Oblig xkcd
|