package FS::Record; use strict; use vars qw($dbdef_file $dbdef $setup_hack $AUTOLOAD @ISA @EXPORT_OK $DEBUG); use subs qw(reload_dbdef); use Exporter; use Carp qw(carp cluck croak confess); use File::CounterFile; use Locale::Country; use DBIx::DBSchema; use FS::UID qw(dbh checkruid getotaker datasrc driver_name); @ISA = qw(Exporter); @EXPORT_OK = qw(dbh fields hfields qsearch qsearchs dbdef); $DEBUG = 0; #ask FS::UID to run this stuff for us later $FS::UID::callback{'FS::Record'} = sub { $File::CounterFile::DEFAULT_DIR = "/usr/local/etc/freeside/counters.". datasrc; $dbdef_file = "/usr/local/etc/freeside/dbdef.". datasrc; &reload_dbdef unless $setup_hack; #$setup_hack needed now? }; =head1 NAME FS::Record - Database record objects =head1 SYNOPSIS use FS::Record; use FS::Record qw(dbh fields qsearch qsearchs dbdef); $record = new FS::Record 'table', \%hash; $record = new FS::Record 'table', { 'column' => 'value', ... }; $record = qsearchs FS::Record 'table', \%hash; $record = qsearchs FS::Record 'table', { 'column' => 'value', ... }; @records = qsearch FS::Record 'table', \%hash; @records = qsearch FS::Record 'table', { 'column' => 'value', ... }; $table = $record->table; $dbdef_table = $record->dbdef_table; $value = $record->get('column'); $value = $record->getfield('column'); $value = $record->column; $record->set( 'column' => 'value' ); $record->setfield( 'column' => 'value' ); $record->column('value'); %hash = $record->hash; $hashref = $record->hashref; $error = $record->insert; #$error = $record->add; #depriciated $error = $record->delete; #$error = $record->del; #depriciated $error = $new_record->replace($old_record); #$error = $new_record->rep($old_record); #depriciated $value = $record->unique('column'); $value = $record->ut_float('column'); $value = $record->ut_number('column'); $value = $record->ut_numbern('column'); $value = $record->ut_money('column'); $value = $record->ut_text('column'); $value = $record->ut_textn('column'); $value = $record->ut_alpha('column'); $value = $record->ut_alphan('column'); $value = $record->ut_phonen('column'); $value = $record->ut_anything('column'); $value = $record->ut_name('column'); $dbdef = reload_dbdef; $dbdef = reload_dbdef "/non/standard/filename"; $dbdef = dbdef; $quoted_value = _quote($value,'table','field'); #depriciated $fields = hfields('table'); if ( $fields->{Field} ) { # etc. @fields = fields 'table'; #as a subroutine @fields = $record->fields; #as a method call =head1 DESCRIPTION (Mostly) object-oriented interface to database records. Records are currently implemented on top of DBI. FS::Record is intended as a base class for table-specific classes to inherit from, i.e. FS::cust_main. =head1 CONSTRUCTORS =over 4 =item new [ TABLE, ] HASHREF Creates a new record. It doesn't store it in the database, though. See L<"insert"> for that. Note that the object stores this hash reference, not a distinct copy of the hash it points to. You can ask the object for a copy with the I method. TABLE can only be omitted when a dervived class overrides the table method. =cut sub new { my $proto = shift; my $class = ref($proto) || $proto; my $self = {}; bless ($self, $class); $self->{'Table'} = shift unless defined ( $self->table ); my $hashref = $self->{'Hash'} = shift; foreach my $field ( $self->fields ) { $hashref->{$field}='' unless defined $hashref->{$field}; #trim the '$' and ',' from money fields for Pg (belong HERE?) #(what about Pg i18n?) if ( driver_name =~ /^Pg$/i && $self->dbdef_table->column($field)->type eq 'money' ) { ${$hashref}{$field} =~ s/^\$//; ${$hashref}{$field} =~ s/\,//; } } $self; } sub create { my $proto = shift; my $class = ref($proto) || $proto; my $self = {}; bless ($self, $class); if ( defined $self->table ) { cluck "create constructor is depriciated, use new!"; $self->new(@_); } else { croak "FS::Record::create called (not from a subclass)!"; } } =item qsearch TABLE, HASHREF, SELECT, EXTRA_SQL Searches the database for all records matching (at least) the key/value pairs in HASHREF. Returns all the records found as `FS::TABLE' objects if that module is loaded (i.e. via `use FS::cust_main;'), otherwise returns FS::Record objects. ###oops, argh, FS::Record::new only lets us create database fields. #Normal behaviour if SELECT is not specified is `*', as in #C