GSP
Quick Navigator

Search Site

Unix VPS
A - Starter
B - Basic
C - Preferred
D - Commercial
MPS - Dedicated
Previous VPSs
* Sign Up! *

Support
Contact Us
Online Help
Handbooks
Domain Status
Man Pages

FAQ
Virtual Servers
Pricing
Billing
Technical

Network
Facilities
Connectivity
Topology Map

Miscellaneous
Server Agreement
Year 2038
Credits
 

USA Flag

 

 

Man Pages
Oryx::Manual::Guts(3) User Contributed Perl Documentation Oryx::Manual::Guts(3)

Oryx::Manual::Guts - Oryx internals documentation for developers

This document is intended for hackers to grant an insight into how Oryx's pieces fit together and is intended for anyone wishing to extend Oryx... or for anybody who just wants to know how the sausage is made.

Oryx implements an object oriented meta-model, that is, information about persistent classes is carried around, usually as instances of meta classes, by the persistent classes themselves, instances of which are your persistent objects.

This makes it difficult to describe a meta-model which has components, or meta-components, which themselves are really just ordinary Perl objects.

Thus we could end up talking about instances of the Oryx::Value::String class being associated with an instance of the Oryx::Attribute class when mentioning how they relate to our persistant objects - which are themselves Oryx::Class derived instances. All of which can be tricky for the brain (well mine, at any rate) to keep a grip on.

So to make this slightly more coherent, we'll stick to the following nomenclature throughout this document:

class
When we say "class" we mean a subclass of "Oryx::Class" which you can instantiate into "objects" which are persistable in some storage backend - usually a database of sorts.
object
When we refer to "objects" we mean our persistent objects - that is, instances of subclasses of Oryx::Class which we're interested in storing in our database.
meta-type
We'll use "meta-type" when talking about meta classes of which Oryx::Attribute and Oryx::Association are two examples (not to be confused with instances of these described under meta-instances below).
meta-instance
These are actually objects themselves (but not of the kind described above under "object") and are considered meta data of the "class" in that they hold descriptive information about the "classes". Examples are instances of Oryx::Attribute and Oryx::Association.
meta-attribute
When we say: "meta-attribute", what we mean varies. To explain: two methods are available for accessing these and are inherited by all meta-types from Oryx::MetaClass. The methods are "getMetaAttribute" and "setMetaAttribute". Exactly what these access depends on the context, that is to say, the term "meta" here is relative to the meta-type on which the method is called. So if we say:

    CMS::Page->attributes->{number}->getMetaAttribute('type');
    

We will get a string representing the type of the value which may be stored in this field of the object, most likely an 'Integer' in this case. On the other hand, if we say:

    CMS::Page->association->{paragraphs}->getMetaAttribute('class');
    

We will get the name of the target class of the 'paragraphs' association, probably "CMS::Paragraph" in this case, which is a class name - in fact a subclass of Oryx::Class - which is not an Oryx meta-type, but in this context, it is meta-data which this association needs in order to perform its duty.

Oryx implements an abstract metamodel which can be specialised to work with any storage backend. At the moment relational databases and a fast, pure Perl file-based database are supported, but the abstraction of the metamodel should allow one to add support for any other storage backend without changing how persistent classes are defined.

This abstract metamodel consist of four base meta-types namely: Oryx::Attribute, Oryx::Association, Oryx::Parent and Oryx::Class. Oryx::Class can be regarded as a special case meta-type in that it is the level at which our meta-model joins Perl's own built-in object model.

When a persistent class inherits from Oryx::Class, it doesn't have the implementation to be persisted in any given storage back-end, that is, the methods for creating, retrieving, updating, etc. are just stubs and will raise an exception if invoked. During a call to "Oryx->connect(...)", however, Oryx looks at the connection arguments and determines which concrete meta-types will be used thereafter. This is done by simply pushing either Class::DBI::Class or Class::DBM::Class onto @Oryx::Class::ISA, thereby effectively doing dynamic, run-time inheritance. So for example, if we say:

    use Oryx;
    use CMS::Page;
     
    UNIVERSAL::isa(CMS::Page, 'Oryx::Class')            # true
    UNIVERSAL::isa(CMS::Page, 'Oryx::DBI::Class')       # false
     
    Oryx->connect('dbi:Pg:dbnam=foo', $user, $pass);
    
    UNIVERSAL::isa(CMS::Page, 'Oryx::DBI::Class')       # true

whereas if we:

    Oryx->connect('dbm:Deep:datapath=/path/to/data');
    
    UNIVERSAL::isa(CMS::Page, 'Oryx::DBM::Class')       # true

From this point onwards, the correct concrete meta-types are used and constructed from the class metadata defined in the class' $schema. This happens in the class's "import" hook, but is usually deferred to happen at run-time (instead of compile-time); so in the first case above this would be Oryx::DBI::Association, Oryx::DBI::Attribute and Oryx::DBI::Parent. The actual "connect()" call is then delegated to the appropriate storage class: Oryx::DBI or Oryx::DBM, as the case may be. These storage classes handle low level connection, pinging the DB and caching database handles (indirectly via Ima::DBI) where applicable.

Each Oryx::Class derivative (or subclass) has any number of instances of the concrete meta-types associated with it. At the Oryx::Class level, this is done with inheritable class data using Class::Data::Inheritable (of all things!) for creating accessors (or "named closures"), typically by inspecting the $schema class variable, or, in the case of Oryx::Parent meta-instances, by inspecting the class' @ISA array.

From our class, we can access the meta-instances as folows:

    @attribs = values %{CMS::Page->attributes};            # all the attributes
    $assoc  = CMS::Page->associations->{paragraphs};       # single association

Oryx::Parent meta-instances are stored in an array ref, so this access looks a little different:

    @parents = @{CMS::Page->parents};      # all parents

Alternatively you can get all the meta-instances as an array using the convenient "members" method:

    @members = CMS::Page->members;

This will then contain a list of all the meta-instances describing our "CMS::Page" class.

NOTE: The meta-instances are constructed using "import", so they'll be there after you "use" the class, but not if you just "require" it.

Attributes
Attributes create individual fields of data with each row (columns). Attributes have a field name and a type.
Associations
Associations create relationships between Oryx objects. These relationship are mapped using Perl references, arrays, or hashes.
Parents
Oryx classes may subclass other Oryx classes, inheriting all fields the parents provide.

These all inherit from a common base meta-type: Oryx::MetaClass and they all implement a common interface described therein.

The overall interface of each Oryx object defines six main methods. At the top level, each of these methods may perform some action as well as delegating additional actions out to each member class (see "meta-types"). Thus, the implementation of each of each of these methods in the Oryx class looks something like:

  sub create {
      # take some action to create the record
      $_->create(...) foreach $class->members;
      # finish up, store the data, return
  }
create
This method is called to create a new record in storage.
retrieve
This method is called to fetch an object from storage by the object's identifier.
update
After making changes to the object, this method records those changes to storage.
delete
This method deletes the object. The object is invalid after this method is called and should not be referred to anymore.
search
This method is responsible for searching by field and returning an array of matching objects.
construct
When searching and retrieving, both instantiate each instance returned using this method.

Each delegated class has a chance to modify the object as necessary during each of these calls.

Oryx has a few special unique parts that are used to define the rest. The most visible of these parts are the Oryx and Oryx::Class objects.

Each of the following headings describe each group of classes used by Oryx.

There are two classes that any Oryx user must be familiar with. The rest of the classes in the system work through the meta-model of Oryx and are not necessarily exposed directly to the user.

In order to establish a connection to storage, the user uses methods of the Oryx class. Then, to define a class, the user typically extends Oryx::Class to automatically configure the class from a meta-model representation.

The third front-end class is Oryx::Schema, which can be subclassed by the user to change groups of classes in the same storage schema.

Oryx
This class is responsible for initializing the general state of Oryx. It provides the "connect()" method which initializes the connection to storage, provides a method for deploying a whole schema, "deploySchema()".
Oryx::Class
By subclassing this class, an object allows metadata declared in the $schema package variable or XML in the "__DATA__" section to be parsed and used to build class methods and schema information. Each persistent Oryx object should subclass this class.
Oryx::Schema
Provides a basic template for Oryx schemas. The schema used for an object is picked when a connection is made to storage. This schema is used by default. This schema class may be subclassed to change the table prefix for objects in the schema or make other modifications to the schema as a whole.

These objects are used under the hood to perform the basic row-level operations for a persistent Oryx class. All Oryx classes ultimately inherit functionality from Oryx::MetaClass. All will inherit functionality from either Oryx::DBM::Class or Oryx::DBI::Class depending on the storage type.
Oryx::MetaClass
This class provides access to an object's metadata.
Oryx::DBI::Class
This provides the basic functionality required to store an object into a DBI connected database.
Oryx::DBM::Class
This provides the basic functionality required to store an object into a DBM connected database.

The member classes in the meta-model create additional functionality within a database row. These classes are associated with an object as configured by the schema of the class.
Oryx::Association
This is the base class for associations. Associations connect one Oryx object instance to another or to a group of others. Exactly how the association functions depends on the association type.
Oryx::Association::Array
This is an association class that is used for "Array" associations. This creates a one-to-many mapping. The mapping is performed using a Perl array.
Oryx::Association::Hash
This is an association class that is used for "Hash" associations. This creates a named one-to-many mapping. The mapping is performed using a Perl hash.
Oryx::Association::Reference
This is an association class that is used for "Reference" associations. This creates a one-to-one mapping. The mapping is performed using a simple Perl reference.
Oryx::Attribute
Attributes are added to Oryx objects to include primitive data associated with the object. Each attribute has a type associated with it, which are managed via Oryx::Value classes (see "ATTRIBUTE VALUE CLASSES").
Oryx::Parent
One of the main goals of Oryx is to map Perl objects into persistent data storage in a way that fits natrually into Perl's object-model. One of the important features of this object-model is the ability to subclass. The Oryx::Parent delivers the functionality required to make this work seamlessly.

Currently, Oryx supports to types of backing stores via DBI or DBM::Deep. These classes are responsible for making the connections to those objects when the "connect()" method of Oryx is called. These are also responsible for making the work of deploying objects and schemas happen.
Oryx::DBI
This manages connectivity and deployment to a DBI connection.
Oryx::DBM
This manages connectivity and deployment to a DBM::Deep connection.

These are helpers used by Oryx::DBI and Oryx::DBM to do much of the grunt work over the storage connection.
Oryx::DBI::Util
This documents the interface that is actually implemented by drivers. Drivers must implement methods for testing for checking for and manipulating table columns, checking for and manipulating table definitions, manipulating sequences, manipulating indexes, discerning types, and enumerating rows.
Oryx::DBI::Util::mysql
This is the driver for DBD::mysql connections.
Oryx::DBI::Util::Pg
This is the driver for DBD::Pg connections.
Oryx::DBI::Util::SQLite
This is the driver for DBD::SQLite connections.
Oryx::DBM::Util
This is the analog for Oryx::DBI::Util that works with Oryx::DBM. Provides functionality for checking for and manipulating tables and sequences.

These classes all implement the specifics of the "META-MODEL MEMBER CLASSES". These simply implement the functionality for the Oryx::DBI storage object.
Oryx::DBI::Association
Oryx::DBI::Association::Array
Oryx::DBI::Association::Hash
Oryx::DBI::Association::Reference
Oryx::DBI::Attribute
Oryx::DBI::Parent

These classes all implement the specifics of the "META-MODEL MEMBER CLASSES". These simply implement the functionality for the Oryx::DBM storage object.
Oryx::DBM::Association
Oryx::DBM::Association::Array
Oryx::DBM::Association::Hash
Oryx::DBM::Association::Reference
Oryx::DBM::Attribute
Oryx::DBM::Class
Oryx::DBM::Parent

These are used by Oryx::Attribute and Oryx::Association members to choose how to validate, load, and store information in each for each column. Each of these is a scalar tie object.

Each of these defined "TIESCALAR()", "FETCH()", and "STORE()". See perltie for more details.

Oryx::Value
This provides a default implementation and the general interface for all the others.
Oryx::Value::Binary
This provides an implementation for BLOB-style binary data.
Oryx::Value::Boolean
This provides an implementation for a binary value of either 0 or 1.
Oryx::Value::Complex
This provides an implementation of YAML encoded references.
Oryx::Value::DateTime
This provides an implementation of date/time data.
Oryx::Value::Float
This provides an implementation of floating point data.
Oryx::Value::Integer
This provides an implementation of integer data.
Oryx::Value::Oid
This provides an implementation for object identifiers, which are used as primary keys for objects.
Oryx::Value::String
This provides an implementation for string data---generally shorter than 256 characters.
Oryx::Value::Text
This provides an implementation for long text data.

This documentation contributed by Andrew Sterling Hanenkamp <hanenkamp@cpan.org>

Copyright (c) 2005 Richard Hundt <richard NO SPAM AT protea-systems.com>

Oryx may be used under the same terms as Perl itself.
2005-12-30 perl v5.32.1

Search for    or go to Top of page |  Section 3 |  Main Index

Powered by GSP Visit the GSP FreeBSD Man Page Interface.
Output converted with ManDoc.