Data Objects

I’d like to add support for data objects in the style of Ruby on Rails' “Active Records”, which allow a object to be linked to a database table, providing much easier manipulation of data.

Example

Since a block code can say a thousand words, heres one:

<?php
// Person is an object which extends JawsDBO, and defines the layout of the table.
$person = new Person();
 
// JawsDBO::Set* allows custom methods to be written for input validation etc.
// For example Person::SetEMail() could check that a valid e-mail address is provided.
$person->SetName("Jon Wood");
$person->SetEMail("jon@jellybob.co.uk");
 
// $result == JawsError||true
if ($result = $person->Insert()) {
    $people = Person::GetAll();
    while ($people->Fetch())
        echo "<em>".$people->GetName()."</em> ".$people->GetEMail()."<br />";
} else {
    echo $result->GetMessage();
}
?>

Proposed Features

Automated construction of WHERE statements.

The main method of setting conditions to match will be something like this:

<?php
$person = new Person();
$person->SetName("Jon");
$person->SetEMail("jon@jellybob.co.uk");
 
// This will build a query like: SELECT * FROM people WHERE name="jon" AND email="jon@jellybob.co.uk"
$person->Get();
?>

Some method of doing searches which aren’t exact matches will also be needed, either:

  $person->AddCondition("age > 20");

or

  $person->SetAge(20, ">");

Mapping of values to objects

I’m not sure how we’d achieve this one, but it would be really nice if values could be mapped to objects themselves, so for example a group object would be able to map the member id field to a Person object, allowing code like this:

<?php
$group = new Group();
$group->SetName("admins");
$group->Get();
 
while($member = $group->GetNextMember())
    echo $member->GetName()."<br />";
?>

Data Object Setup

ActiveRecord automatically loads the object by reading the database schema, but I’d rather avoid that for something a little more manual, since it means that you have less flexibility when mapping objects to database tables.

Because of that the object’s constructor should probably contain some setup code like this:

<?php
class Person extends JawsDBO
{
    function Person()
    {
        $this->_Table("people");
        $this->AddKeyField("id", JAWSDBO_TYPE_INT);
        $this->AddField("name", JAWSDBO_TYPE_STRING, array("length" => "255",
                                                            "required" => true));
        $this->AddField("email", JAWSDBO_TYPE_STRING, array("length" => "255"));
        $this->AddField("age", JAWSDBO_TYPE_INT, array("length", 11));
    }
}
?>

This needs some thinking though, since the third parameter being an array of settings for the field seems clunky.

  Having thought about this a bit more, I think it would be nice to allow auto-setup if the user wants it, probably by calling a method such as AutoSetup(); which would query the the table schema.

Type Conversions

Data will be automatically converted into the appropriate type as defined in the schema.

For example JAWSDBO_TYPE_DATETIME will indicate that the data in the field should be converted to a JawsDate.

Transformations

Using a selection of standard ToType methods it will be possible to convert the object into different types.

Method
ToString Converts the object to a string representation.
ToArray Returns the object as an array of values.
ToForm Returns a ready to use Piwi form for this object.
ToWidget Returns the appropriate widget for a single field.

Proposal Information

Author: Jon Wood, jon@jellybob.co.uk
Last Updated: 22:28 BST, 10/04/2005

Comments

One cool thing about Rails is that you can easily initialze objects from the request data by using the ‘set attributes’ method. Rails also has lots of callback methods which you can use to customize the behaviour.

 
  /var/www/wiki/htdocs/data/jaws/proposals/data_objects.txt · Last modified: 2007/11/02 16:27