Rose::DB::Object provides an object representation of databse rows.
It addresses some of the same problems as Class:DBI, Alzabo, et al,
but it takes a slightly different appraoch. It's still in the early
stages of development, but it's fully documented and has a large test
suite already.

I'm looking for developers who are either unsatisfied with existing
OO-RDBMS mapping modules or are just curious to help me ring the
code out. Comments, suggestion, and of course bug reports are very
welcome.

Excerpts from the documentation follow.

-John

---

NAME
Rose::DB::Object - Object representation of a single row in a database
table.

SYNOPSIS
package Category;

use Rose::DB::Object;
our @ISA = qw(Rose::DB::Object);

__PACKAGE__->meta->table('categories');

__PACKAGE__->meta->columns
(
id => { type => 'int', primary_key => 1 },
name => { type => 'varchar', length => 255 },
description => { type => 'text' },
);

__PACKAGE__->meta->add_unique_key('name');

__PACKAGE__->meta->initialize;

...

package Product;

use Rose::DB::Object;
our @ISA = qw(Rose::DB::Object);

__PACKAGE__->meta->table('products');

__PACKAGE__->meta->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' },
);

__PACKAGE__->meta->add_unique_key('name');

__PACKAGE__->meta->foreign_keys
(
category =>
{
class => 'Category',
key_columns =>
{
category_id => 'id',
}
},
);

__PACKAGE__->meta->initialize;

...

$product = Product->new(id => 123,
name => 'GameCube',
status => 'active',
start_date => '11/5/2001',
end_date => '12/1/2007',
category_id => 5);

$product->save or die $product->error;

...

$product = Product->new(id => 123);
$product->load or die $product->error;

print $product->category->name;

$product->end_date->add(days => 45);

$product->save or die $product->error;

...

package Product::Manager;

use Rose::DB::Object::Manager;
our @ISA = qw(Rose::DB::Object::Manager);

sub get_products
{
my $class = shift;

Rose::DB::Object::Manager->get_objects(
object_class => 'Product', @_)
}

sub get_products_iterator
{
my $class = shift;

Rose::DB::Object::Manager->get_objects_iterator(
object_class => 'Product', @_)
}

sub get_products_count
{
my $class = shift;

Rose::DB::Object::Manager->get_objects_count(
object_class => 'Product', @_)
}

...

#
# Get a reference to an array of objects
#

$products =
Product::Manager->get_products
(
query =>
[
category_id => [ 5, 7, 22 ],
status => 'active',
start_date => { lt => '15/12/2005 6:30 p.m.' },
name => { like => [ '%foo%', '%bar%' ] },
],
sort_by => 'category_id, start_date DESC',
limit => 100
)
or die Product::Manager->error;

foreach my $product (@$products)
{
print $product->id, ' ', $product->name, "\n";
}

#
# Get objects iterator
#

$iterator =
Product::Manager->get_products_iterator
(
query =>
[
category_id => [ 5, 7, 22 ],
status => 'active',
start_date => { lt => '15/12/2005 6:30 p.m.' },
name => { like => [ '%foo%', '%bar%' ] },
],
sort_by => 'category_id, start_date DESC',
limit => 100
)
or die Product::Manager->error;

while($product = $iterator->next)
{
print $product->id, ' ', $product->name, "\n";
}

print $iterator->total;

#
# Get objects count
#

$count =
Product::Manager->get_products_count
(
query =>
[
category_id => [ 5, 7, 22 ],
status => 'active',
start_date => { lt => '15/12/2005 6:30 p.m.' },
name => { like => [ '%foo%', '%bar%' ] },
],
limit => 100
);

die Product::Manager->error unless(defined $count);

print $count; # or Product::Manager->total()

#
# Get objects and sub-objects in a single query
#

$products =
Product::Manager->get_products
(
with_objects => [ 'category' ],
query =>
[
category_id => [ 5, 7, 22 ],
status => 'active',
start_date => { lt => '15/12/2005 6:30 p.m.' },
name => { like => [ '%foo%', '%bar%' ] },
],
sort_by => 'category_id, start_date DESC',
limit => 100
)
or die Product::Manager->error;

foreach my $product (@$products)
{
print $product->name, ': ', $product->category->name, "\n";
}