package Rose::DB::Object::Std;
use strict;
use Rose::DB::Object::Std::Metadata;
use Rose::DB::Object;
our @ISA = qw(Rose::DB::Object);
our $VERSION = '0.021';
our $Debug = 0;
#
# Class methods
#
sub meta_class { 'Rose::DB::Object::Std::Metadata' }
#
# Object methods
#
# Better to leave this up to the database...
# sub insert
# {
# my($self) = shift;
#
# my $meta = $self->meta;
#
# if($meta->column('date_created'))
# {
# $self->date_created('now') unless($self->date_created);
# }
#
# if($meta->column('last_modified'))
# {
# $self->last_modified('now');
# }
#
# $self->SUPER::insert(@_);
# }
#
# sub update
# {
# my($self) = shift;
#
# if($self->meta->column('last_modified'))
# {
# $self->last_modified('now');
# }
#
# $self->SUPER::update(@_);
# }
1;
__END__
=head1 NAME
Rose::DB::Object::Std - Standardized object representation of a single row in a database table.
=head1 SYNOPSIS
package Category;
use base 'Rose::DB::Object::Std';
__PACKAGE__->meta->setup
(
table => 'categories',
columns =>
[
id => { type => 'int', primary_key => 1 },
name => { type => 'varchar', length => 255 },
description => { type => 'text' },
],
unique_key => 'name',
);
...
package Product;
use base 'Rose::DB::Object::Std';
__PACKAGE__->meta->setup
(
table => 'products',
columns =>
[
id => { type => 'int', primary_key => 1 },
name => { type => 'varchar', length => 255 },
description => { type => 'text' },
category_id => { type => 'int' },
status =>
{
type => 'varchar',
check_in => [ 'active', 'inactive' ],
default => 'inactive',
},
start_date => { type => 'datetime' },
end_date => { type => 'datetime' },
date_created => { type => 'timestamp', default => 'now' },
last_modified => { type => 'timestamp', default => 'now' },
],
unique_key => 'name',
foreign_keys =>
[
category =>
{
class => 'Category',
key_columns => { category_id => 'id' },
},
],
);
...
$product = Product->new(name => 'GameCube',
status => 'active',
start_date => '11/5/2001',
end_date => '12/1/2007',
category_id => 5);
$product->save or die $product->error;
$id = $product->id; # auto-generated on save
...
$product = Product->new(id => $id);
$product->load or die $product->error;
print $product->category->name;
$product->end_date->add(days => 45);
$product->save or die $product->error;
...
=head1 DESCRIPTION
L<Rose::DB::Object::Std> is a subclass of L<Rose::DB::Object> that imposes a few more constraints on the tables it fronts. In addition to the constraints described in the L<Rose::DB::Object> documentation, tables fronted by L<Rose::DB::Object::Std> objects must also fulfill the following requirements:
=over 4
=item * The table must have a single primary key column named "id"
=item * The value of the "id" column must be auto-generated if absent.
=back
Different databases provide for auto-generated column values in different ways. Some provide a native "auto-increment" or "serial" data type, others use sequences behind the scenes.
L<Rose::DB::Object::Std> (in cooperation with L<Rose::DB> and L<Rose::DB::Object::Std::Metadata>) attempts to hide these details from you. All you have to do is omit the value for the primary key entirely. After the object is C<save()>ed, you can retrieve the auto-selected primary key by calling the C<id()> method.
You do have to correctly define the "id" column in the database, however. Here are examples of primary key column definitions that provide auto-generated values, one for each of the databases supported by L<Rose::DB>.
=over
=item * PostgreSQL
CREATE TABLE mytable
(
id SERIAL NOT NULL PRIMARY KEY,
...
);
=item * MySQL
CREATE TABLE mytable
(
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
...
);
=item * Informix
CREATE TABLE mytable
(
id SERIAL NOT NULL PRIMARY KEY,
...
);
=back
Other data definitions are possible, of course, but the three definitions above are used in the L<Rose::DB::Object::Std> test suite and are therefore guaranteed to work. If you have success with alternative approaches, patches and/or new tests are welcome.
To achieve much of this functionality, L<Rose::DB::Object::Std> uses L<Rose::DB::Object::Std::Metadata> objects. The C<meta()> method will create these form you. You should not need to do anything special if you use the idiomatic approach to defining metadata as shown in the L<synopsis|/SYNOPSIS>.
=head1 METHODS
Only the methods that are overridden are documented here. See the L<Rose::DB::Object> documentation for the rest.
=over 4
=item B<meta>
Returns the L<Rose::DB::Object::Std::Metadata> object associated with this class. This object describes the database table whose rows are fronted by this class: the name of the table, its columns, unique keys, foreign keys, etc. See the L<Rose::DB::Object::Std::Metadata> documentation for more information.
This can be used as both a class method and an object method.
=back
=head1 AUTHOR
John C. Siracusa (siracusa@gmail.com)
=head1 LICENSE
Copyright (c) 2010 by John C. Siracusa. All rights reserved. This program is
free software; you can redistribute it and/or modify it under the same terms
as Perl itself.