Oryx
view release on metacpan or search on metacpan
lib/Oryx.pm view on Meta::CPAN
Searching uses 'LIKE' (assuming an RDBMS storage) :
my @pages = CMS::Page->search({ author => '%Hundt%'});
B<NOTE> : Searches don't search through superclass fields yet...
=head1 INHERITANCE
Inheritance works as you would expect.
So if we have the following :
package CMS::Section;
use base qw(Oryx::Class);
# ... schema definition here ...
1;
package CMS::Paragraph;
use base qw(CMS::Section);
# ... schema definition here ...
1;
You get exactly what you would normally get in Perl, that is :
UNIVERSAL::isa('CMS::Paragraph', 'Oryx::Class')
holds true and attributes and associations defined in CMS::Section are
available to CMS::Paragraph instances. So any class which has
persistant class as an ancestor, can be treated and persisted in the
same way as the ancestor. However, it is important to note that it
gets its own table in the database.
For multiple persistent base classes :
package Orange;
use base qw(Food Fruit);
As long as Food and Fruit are Oryx::Class derivatives,
the Force That Into the Database Drives the Object will make sure the
proverbial Right Thing is Done.
Oryx uses a multiple table inheritance model (as opposed to putting
all the instances for classes in an inheritance chain into the same
table), each subclass instance has a corresponding superclass instance
for each superclass (assuming said superclass is a derivative of
Oryx::Class), so that attributes which exists in the superclass are
stored (as a row) in the superclass' table, and are therefore fully
fledged instances of the superclass.
You can access these superclass instances with the I<PARENT> method as
follows:
my $parent_section_instance = $paragraph->PARENT('CMS::Section');
and then use this instance normally.
Updates and deletes cascade up the inheritance chain, as you'd expect.
=head1 ABSTRACT CLASSES
Abstract classes to Oryx are simply classes which do not define any
attributes, but may have associations. The effect is automatic.
Abstract classes behave slightly differently to concrete classes
(which define attributes) in that if you I<retrieve> an instance of an
abstract class (by id or by accessing a member of an association), you
get an instance of the sub class (the one which created the row in the
abstract class's table).
This is particularly useful where you have an Array or Hash
association between two classes and need to mix instances of different
types in that association. As long as all the members of the array (or
hash) inherit from the same abstract class, accessing them produces
the expected result.
Consider the following case :
<ABSTRACT>
+------+ <Array> +----------+
| Page |----------| Fragment |
+------+ frags +----------+
|______| |__________|
/_\
|
+---------+------+
| |
+-----------+ +-------+
| Paragraph | | Image |
+-----------+ +-------+
|___________| |_______|
Here the I<Paragraph> and I<Image> both inherit from the abstract
I<Fragment> class. When the I<frags> Array association is accessed
it may contain a mixture of both I<Paragraph> and I<Image> instances.
Thus you can say:
$my_para = Paragraph->create({ ... });
$my_page->frags->[42] = $my_para;
$my_img = Image->create({ ... });
$my_page->frags->[69] = $my_img;
pretty neat huh?
=head1 OBJECT CACHING
In the interest of consistency, objects are cached and
are unique in memory. Therefore, if you retrieve an object
more than once, each subsequent retrieve until the reference
count on it has dropped to zero and has been eaten by the garbage
collector, will return a reference to the same object.
This has a performance gain in certain situations too.
=head1 CONNECTING TO STORAGE
( run in 1.299 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )