package DBIx::Custom::Model; use Object::Simple -base; use Carp 'croak'; use DBIx::Custom::Util '_subname'; # Carp trust relationship push @DBIx::Custom::CARP_NOT, __PACKAGE__; has [qw/dbi table created_at updated_at bind_type join primary_key/], columns => sub { [] }; our $AUTOLOAD; sub AUTOLOAD { my $self = shift; # Method name my ($package, $mname) = $AUTOLOAD =~ /^([\w\:]+)\:\:(\w+)$/; # Method $self->{_methods} ||= {}; if (my $method = $self->{_methods}->{$mname}) { return $self->$method(@_) } elsif (my $dbi_method = $self->dbi->can($mname)) { $self->dbi->$dbi_method(@_); } elsif ($self->{dbh} && (my $dbh_method = $self->dbh->can($mname))) { $self->dbi->dbh->$dbh_method(@_); } else { croak qq{Can't locate object method "$mname" via "$package" } . _subname; } } my @methods = qw/insert insert_at update update_at update_all delete delete_at delete_all select select_at count/; for my $method (@methods) { my $code = sub { my $self = shift; unless ($self->{_attribute_cache}{$self}) { $self->$_ for qw/table bind_type primary_key type join created_at updated_at/; $self->{_attribute_cache}{$self} = 1; } $self->dbi->$method( @_ % 2 ? shift : (), table => $self->{table}, exists $self->{type} ? (type => $self->{type}) : (), exists $self->{created_at} && $method eq 'insert' ? (created_at => $self->{created_at}) : (), exists $self->{updated_at} && ($method eq 'insert' || $method eq 'update') ? (updated_at => $self->{updated_at}) : (), exists $self->{bind_type} ? (bind_type=> $self->{bind_type}) : (), exists $self->{primary_key} ? (primary_key => $self->{primary_key}) : (), exists $self->{join} && index($method, 'select') != -1 ? (join => $self->{join}) : (), @_ ) }; no strict 'refs'; my $class = __PACKAGE__; *{"${class}::$method"} = $code; } sub execute { my $self = shift; return $self->dbi->execute( shift, shift, table => $self->table, bind_type => $self->bind_type, primary_key => $self->primary_key, type => $self->type, @_ ); } sub DESTROY { } sub helper { my $self = shift; # Merge my $methods = ref $_[0] eq 'HASH' ? $_[0] : {@_}; $self->{_methods} = {%{$self->{_methods} || {}}, %$methods}; return $self; } sub mycolumn { my $self = shift; my $table = shift unless ref $_[0]; my $columns = shift; $table ||= $self->table || ''; $columns ||= $self->columns; return $self->dbi->mycolumn($table, $columns); } sub new { my $self = shift->SUPER::new(@_); # Check attribute names my @attrs = keys %$self; for my $attr (@attrs) { croak qq{"$attr" is invalid attribute name } . _subname unless $self->can($attr); } return $self; } # DEPRECATED! has 'filter'; has 'name'; has 'type'; # DEPRECATED! sub method { warn "method method is DEPRECATED! use helper instead"; return shift->helper(@_); } 1; =head1 NAME DBIx::Custom::Model - Model =head1 SYNOPSIS use DBIx::Custom::Model; my $model = DBIx::Custom::Model->new(table => 'books'); =head1 ATTRIBUTES =head2 C my $dbi = $model->dbi; $model = $model->dbi($dbi); L object. =head2 C my $created_at = $model->created_at; $model = $model->created_at('created_datatime'); Create timestamp column, this is passed to C or C method. =head2 C my $join = $model->join; $model = $model->join( ['left outer join company on book.company_id = company.id'] ); Join clause, this value is passed to C method. =head2 C my $model = $model->table; $model = $model->table('book'); Table name, this is passed to C, and C method =head2 C my $updated_at = $model->updated_at; $model = $model->updated_at('updated_datatime'); Updated timestamp column, this is passed to C method. =head1 METHODS L inherits all methods from L, and you can use all methods of L and L and implements the following new ones. =head2 C my $count = $model->count; Get rows count. Options is same as C
and C option. =head2 C $model->delete_all(...); Same as C of L except that you don't have to specify C
and C option. =head2 C $model->execute(...); Same as C of L except that you don't have to specify C
and C option. =head2 C $model->insert(...); Same as C of L except that you don't have to specify C
and C option. =head2 C $model->helper( update_or_insert => sub { my $self = shift; # ... }, find_or_create => sub { my $self = shift; # ... ); Register helper. These helper is called directly from L object. $model->update_or_insert; $model->find_or_create; =head2 C my $column = $self->mycolumn; my $column = $self->mycolumn(book => ['author', 'title']); my $column = $self->mycolumn(['author', 'title']); Create column clause for myself. The follwoing column clause is created. book.author as author, book.title as title If table name is ommited, C
attribute of the model is used. If column names is omitted, C attribute of the model is used. =head2 C my $model = DBIx::Custom::Model->new; Create a L object. =head2 C of L except that you don't have to specify C
, C and C option. =head2 C $model->update(...); Same as C of L except that you don't have to specify C
and C option. =head2 C $model->update_all(param => \%param); Same as C of L except that you don't have to specify C
and C option. =cut