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;
...
DESCRIPTION
Rose::DB::Object
is a base class for objects that encapsulate a single row in a database table. Rose::DB::Object
-derived objects are sometimes simply called "Rose::DB::Object
objects" in this documentation for the sake of brevity, but be assured that derivation is the only reasonable way to use this class.
Rose::DB::Object
objects can represent rows in almost any database table, subject to the following constraints.
The database server must be supported by
Rose::DB
.The database table must have a primary key, and that key must not allow null values in any of its columns.
Although the list above contains the only hard and fast rules, there may be other realities that you'll need to work around.
The most common example is the existence of a column name in the database table that conflicts with the name of a method in the Rose::DB::Object
API. The work-around is to alias the column. See the alias_column()
method in the Rose::DB::Object::Metadata
documentation for more details.
There are also varying degrees of support for data types in each database server supported by Rose::DB
. If you have a table that uses a data type not supported by an existing Rose::DB::Object::Metadata::Column
-derived class, you will have to write your own column class and then map it to a type name using Rose::DB::Object::Metadata
's column_type_class()
method, yada yada.
The entire framework is meant to be extensible. I have created simple implementations of the most common column types, but there's certainly mor ethat could be done. Submissions are welcome.
Rose::DB::Object
provides the following functions:
Create a row in the database by saving a newly constructed object.
Initialize an object by loading a row from the database.
Update a row by saving a modified object back to the database.
Delete a row from the database.
Objects can be loaded based on either a primary key or a unique key. Since all tables fronted by Rose::DB::Object
s must have non-null primary keys, insert, update, and delete operations are done based on the primary key.
This is all very straightforward, but the really handy part is Rose::DB::Object
's ability to parse, coerce, "inflate", and "deflate" column values on your behalf, providing the most convenient possible data representations on the Perl side of the fence, while allowing the programmer to largely forget about the ugly details of the data formats required by the database.
To define your own Rose::DB::Object
-derived class, you must first describe the table that contains the rows you plan to represent. This is done through the Rose::DB::Object::Metadata
object associated with each Rose::DB::Object
-dervied class. (You can see a simple example of this in the synopsis.) The metadata object is accessible via Rose::DB::Object
's meta()
method. See the Rose::DB::Object::Metadata
documentation for more information.
This class inherits from, and follows the conventions of, Rose::Object
. See the Rose::Object
documentation for more information.
CONSTRUCTOR
- new PARAMS
-
Returns a new
Rose::DB::Object
constructed according to PARAMS, where PARAMS are name/value pairs. Any object method is a valid parameter name.
CLASS METHODS
Returns the Rose::DB::Object::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 Rose::DB::Object::Metadata
documentation for more information.
OBJECT METHODS
- db [DB]
-
Get or set the
Rose::DB
object used to access the database that contains the table whose rows are fronted by theRose::DB::Object
-derived class.If it does not already exist, this object is created with a simple, argumentless call to
Rose::DB->new()
. To override this default in a subclass, override theinit_db
method and return theRose::DB
to be used as the new default. - dbh
-
Returns the
DBI
database handle contained indb
. - delete
-
Delete the row represented by the current object. The object must have been previously loaded from the database (or must otherwise have a defined primary key value) in order to be deleted. Returns true if the row was deleted or did not exist, false otherwise.
- error
-
Returns the text message associated with the last error that occurred.
- load
-
Load a row from the database table, initializing the object with the values from that row. An object can be loaded based on either a primary key or a unique key.
Returns true if the row was loaded successfully, false if the row could not be loaded or did not exist.
- not_found
-
Returns true if the previous call to
load()
failed because a row in the database table with the specified primary or unique key did not exist, false otherwise. - meta
-
Returns the
Rose::DB::Object::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
Rose::DB::Object::Metadata
documentation for more information. - save [PARAMS]
-
Save the current object to the database table. In the absence of PARAMS, if the object was previously
load()
ed from the database, the row will be updated. Otherwise, a new row will be created.PARAMS are name/value pairs. Valid parameters are:
insert
If set to a true value, then an insert is attempted, regardless of whether or not the object was previously
load()
ed from the database.update
If set to a true value, then an update is attempted, regardless of whether or not the object was previously
load()
ed from the database.
It is an error to pass both the
insert
andupdate
parameters in a single call.Returns true if the row was inserted or updated successfully, false otherwise.
RESERVED METHODS
As described in the Rose::DB::Object::Metadata
documentation, each column in the database table has an associated get/set accessor method in the Rose::DB::Object
. Since the Rose::DB::Object
API already defines many methods (load()
, save()
, meta()
, etc.), accessor methods for columns that share the name of an existing method pose a problem. The solution is to alias such columns using Rose::DB::Object::Metadata
's alias_column()
method.
Here is a list of method names reserved by the Rose::DB::Object
API. If you have a column with one of these names, you must alias it.
db
dbh
delete
DESTROY
error
init_db
_init_db
insert
load
meta
not_found
save
update
Note that not all of these methods are public. These methods do not suddently become public just because you now know their names! Remember the stated policy of the Rose
web application framework: if a method is not documented, it does not exist. (And no, the above list of method names does not constitute "documentation")
AUTHOR
John C. Siracusa (siracusa@mindspring.com)
COPYRIGHT
Copyright (c) 2005 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.