dicaORM Object-relational mapping

dicaORM Object-relational mapping dicaORM logo

DicaORM is a powerful and easy to use ORM (object-relation mapping) library. It is based on the ActiveRecord pattern. It carries both data and behavior.

DicaORM is probably faster than phpactiverecord because it doesn't parse the database scheme to define the properties. This is also a disadvantage. You still need to define your properties or so called columns for your dicaORM models. In the example below you can see how this is done.

Download

If you want to use it or experiment with it, you can download it. You can clone the latest up-to-date version from my github. I use git to keep track of changes and advise you to do the same ;).

clone git://github.com/dicabrio/dicaORM.git

If you like to contribute, just fork it and start editing! Github is free to use.

Requirements

  • PHP 5
  • PDO

TODO

Anemic Domain Model
These models are still a bit dumb and as some of you know this looks or will look like the Anemic Domain Model and as Martin Fowler states it this is not a good thing. I'm working on adding validators for every column when setting a value and add validators for when saving the object. This way you can add business logic to your model if you like.

Late static binding
In PHP 5.3 Late static binding is available to do some nifty stuff. Check the findAll method in the DataRecord class, you need to define the tablename. I use the Classname (__CLASS__) as a mapping to the tablename and to use the __CLASS__ constant you need to override the findAll method in your own model. This gives clutter in your domain models and is as of PHP 5.3 not necessary anymore.

Observers
I would like to see some form of observable pattern or Listeners in the DataRecord. When some data changes, it can trigger or notify other listeners or observers. This will keep your DataRecord object clean and a lot of code seperate.

Example

MySQL table
for this example I use a MySQL database

CREATE TABLE IF NOT EXISTS `test` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(255) NOT NULL default '',
  `other` varchar(255) NOT NULL default '',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

Now define your model that will write the data to the database. You don't need to write getters and setters. I usually do, because my IDE (Integrated development environment) likes it.

class Test extends DataRecord {

    public function __construct($iID = null) {
        parent::__construct(__CLASS__, $iID);
    }

    // define the method to define the columns to map to the db
    protected function defineColumns() {
        parent::addColumn('id', DataTypes::INT, false, false);
        parent::addColumn('name', DataTypes::VARCHAR, 255, false);
        parent::addColumn('other', DataTypes::VARCHAR, 255, false);
    }

    public static function findAll() {
        return parent::findAll(__CLASS__, self::ALL);
    }
}

Here comes the example

include('datarecord.class.php');
include('column.class.php');
include('columnaggr.class.php');
include('datafactory.class.php');
include('datatypes.class.php');
include('querybuilder.class.php');

try {
    // replace the stars with your data
    $oDatabase = new PDO('mysql:dbname=*****;host=localhost', '****', '****');
    $oData = DataFactory::getInstance();
    $oData->addConnection($oDatabase, 'default');
    $oData->beginTransaction();

    $aAll = Test::findAll();
    foreach ($aAll as $oTesting) {
        $oTesting->delete();
    }

    echo $iRandomValue = mt_rand(1,10);

    $oTest = new Test();
    $oTest->name = 'Robert Cabri'.$iRandomValue;
    $oTest->save();

    $oTest->name = $iRandomValue.'Robert Cabri';
    $oTest->save();

    $oTest2 = new Test($oTest->id);

    $oData->commit();
} catch (Exception $e) {
    echo $e->getMessage();
    $oData->rollBack();
}

Other inspiring ORM libs.

  • Redbean
  • Doctrine
  • Ruby on Rails ActiveRecord
  • PHP activerecord