use Exporter;
use Carp qw(carp cluck croak confess);
use File::CounterFile;
+use Locale::Country;
+use DBIx::DBSchema;
use FS::UID qw(dbh checkruid swapuid getotaker datasrc driver_name);
-use FS::dbdef;
@ISA = qw(Exporter);
@EXPORT_OK = qw(dbh fields hfields qsearch qsearchs dbdef);
$value = $record->ut_alpha('column');
$value = $record->ut_alphan('column');
$value = $record->ut_phonen('column');
- $value = $record->ut_anythingn('column');
+ $value = $record->ut_anything('column');
+ $value = $record->ut_name('column');
$dbdef = reload_dbdef;
$dbdef = reload_dbdef "/non/standard/filename";
$hashref->{$field}='' unless defined $hashref->{$field};
#trim the '$' and ',' from money fields for Pg (belong HERE?)
#(what about Pg i18n?)
- if ( driver_name eq 'Pg'
+ if ( driver_name =~ /^Pg$/i
&& $self->dbdef_table->column($field)->type eq 'money' ) {
${$hashref}{$field} =~ s/^\$//;
${$hashref}{$field} =~ s/\,//;
sub qsearch {
my($table, $record, $select, $extra_sql ) = @_;
+ $table =~ /^([\w\_]+)$/ or die "Illegal table: $table";
+ $table = $1;
$select ||= '*';
my $dbh = dbh;
if ( @fields ) {
$statement .= ' WHERE '. join(' AND ', map {
if ( ! defined( $record->{$_} ) || $record->{$_} eq '' ) {
- if ( driver_name eq 'Pg' ) {
+ if ( driver_name =~ /^Pg$/i ) {
"$_ IS NULL";
} else {
qq-( $_ IS NULL OR $_ = "" )-;
$statement .= " $extra_sql" if defined($extra_sql);
warn $statement if $DEBUG;
- my $sth = $dbh->prepare_cached($statement)
+ my $sth = $dbh->prepare($statement)
or croak "$dbh->errstr doing $statement";
$sth->execute( map $record->{$_},
grep defined( $record->{$_} ) && $record->{$_} ne '', @fields
- ) or croak $dbh->errstr;
+ ) or croak "Error executing \"$statement\": ". $dbh->errstr;
$dbh->commit or croak $dbh->errstr if $FS::UID::AutoCommit;
if ( eval 'scalar(@FS::'. $table. '::ISA);' ) {
my($field)=$AUTOLOAD;
$field =~ s/.*://;
if ( defined($value) ) {
+ confess "errant AUTOLOAD $field for $self (arg $value)"
+ unless $self->can('setfield');
$self->setfield($field,$value);
} else {
$self->getfield($field);
map {
$self->getfield($_) eq ''
#? "( $_ IS NULL OR $_ = \"\" )"
- ? ( driver_name eq 'Pg'
+ ? ( driver_name =~ /^Pg$/i
? "$_ IS NULL"
: "( $_ IS NULL OR $_ = \"\" )"
)
map {
$old->getfield($_) eq ''
#? "( $_ IS NULL OR $_ = \"\" )"
- ? ( driver_name eq 'Pg'
+ ? ( driver_name =~ /^Pg$/i
? "$_ IS NULL"
: "( $_ IS NULL OR $_ = \"\" )"
)
=item unique COLUMN
Replaces COLUMN in record with a unique number. Called by the B<add> method
-on primary keys and single-field unique columns (see L<FS::dbdef_table>).
+on primary keys and single-field unique columns (see L<DBIx::DBSchema::Table>).
Returns the new value.
=cut
my $phonen = $self->getfield($field);
if ( $phonen eq '' ) {
$self->setfield($field,'');
- } elsif ( $country eq 'US' ) {
+ } elsif ( $country eq 'US' || $country eq 'CA' ) {
$phonen =~ s/\D//g;
$phonen =~ /^(\d{3})(\d{3})(\d{4})(\d*)$/
or return "Illegal (phone) $field: ". $self->getfield($field);
$self->setfield($field,$phonen);
} else {
warn "don't know how to check phone numbers for country $country";
- return $self->ut_alphan($field);
+ return $self->ut_textn($field);
}
'';
}
'';
}
+=item ut_name COLUMN
+
+Check/untaint proper names; allows alphanumerics, spaces and the following
+punctuation: , . - '
+
+May not be null.
+
+=cut
+
+sub ut_name {
+ my( $self, $field ) = @_;
+ $self->getfield($field) =~ /^([\w \,\.\-\']+)$/
+ or return "Illegal (name) $field: ". $self->getfield($field);
+ $self->setfield($field,$1);
+ '';
+}
+
+=item ut_zip COLUMN
+
+Check/untaint zip codes.
+
+=cut
+
+sub ut_zip {
+ my( $self, $field ) = @_;
+ $self->getfield($field) =~ /^\s*(\w[\w\-\s]{2,8}\w)\s*$/
+ or return "Illegal (zip) $field: ". $self->getfield($field);
+ $self->setfield($field,$1);
+ '';
+}
+
+=item ut_country COLUMN
+
+Check/untaint country codes. Country names are changed to codes, if possible -
+see L<Locale::Country>.
+
=cut
+sub ut_country {
+ my( $self, $field ) = @_;
+ unless ( $self->getfield($field) =~ /^(\w\w)$/ ) {
+ if ( $self->getfield($field) =~ /^([\w \,\.\(\)\']+)$/
+ && country2code($1) ) {
+ $self->setfield($field,uc(country2code($1)));
+ }
+ }
+ $self->getfield($field) =~ /^(\w\w)$/
+ or return "Illegal (country) $field: ". $self->getfield($field);
+ $self->setfield($field,uc($1));
+ '';
+}
+
=item ut_anything COLUMN
Untaints arbitrary data. Be careful.
sub ut_anything {
my($self,$field)=@_;
- $self->getfield($field) =~ /^(.*)$/
+ $self->getfield($field) =~ /^(.*)$/s
or return "Illegal $field: ". $self->getfield($field);
$self->setfield($field,$1);
'';
This can be used as both a subroutine and a method call. It returns a list
of the columns in this record's table, or an explicitly specified table.
-(See L<FS::dbdef_table>).
+(See L<DBIx::DBSchema::Table>).
=cut
$table_obj->columns;
}
+=back
+
=head1 SUBROUTINES
=over 4
=item reload_dbdef([FILENAME])
-Load a database definition (see L<FS::dbdef>), optionally from a non-default
-filename. This command is executed at startup unless
-I<$FS::Record::setup_hack> is true. Returns a FS::dbdef object.
+Load a database definition (see L<DBIx::DBSchema>), optionally from a
+non-default filename. This command is executed at startup unless
+I<$FS::Record::setup_hack> is true. Returns a DBIx::DBSchema object.
=cut
sub reload_dbdef {
my $file = shift || $dbdef_file;
- $dbdef = load FS::dbdef ($file);
+ $dbdef = load DBIx::DBSchema $file;
}
=item dbdef
=head1 VERSION
-$Id: Record.pm,v 1.12 2001-02-03 14:03:49 ivan Exp $
+$Id: Record.pm,v 1.24 2001-08-19 00:48:49 ivan Exp $
=head1 BUGS
The Pg money kludge in the new method only strips `$'.
-The ut_phonen method assumes US-style phone numbers.
+The ut_phonen method only checks US-style phone numbers.
The _quote function should probably use ut_float instead of a regex.
or allow it to be set. Working around it is ugly any way around - DBI should
be fixed. (only affects RDBMS which return uppercase column names)
+ut_zip should take an optional country like ut_phone.
+
=head1 SEE ALSO
-L<FS::dbdef>, L<FS::UID>, L<DBI>
+L<DBIx::DBSchema>, L<FS::UID>, L<DBI>
Adapter::DBI from Ch. 11 of Advanced Perl Programming by Sriram Srinivasan.