RapidDataMapper - PHP Data Mapper ORM

About

RapidDataMapper is an Object-Relational-Mapper (ORM) and a database abstraction layer for the PHP programming language. It has been designed to be fast, flexible, secure, and easy to learn.

Flexibility

RapidDataMapper has been designed with adaptability in mind. To help the developer, it assumes a lot of defaults values. This means that you can use the library “as is” or adapt those parameters at will and replace almost any values. This mindset also has been applied to the mappers, making it possible to replace much of the mapping logic by injecting alternative code.

Framework Agnostic

Frameworks, frameworks, frameworks. Everyone wants frameworks, and no body agrees on which one to use! Fortunately, RapidDataMapper does not require a framework to run, nor does it depend on other PHP libraries. This makes it possible to use RapidDataMapper with the framework of your choice!

Performance

By creating customized mapper code, RapidDataMapper provide a very fast and efficient way to access your data and to execute your data logic. This means that no unnecessary code is loaded once a mapper has been cached, making it even more resource-efficient.

Downloads

Here is a list of download packages for RapidDataMapper; they contain the source code, manual (including DocBook sources), API documentation (from phpDocumentor), code coverage report (from PHPUnit), test cases and framework compatibility files.

Stable

Compatible Frameworks

The included framework compatibility files are made to help RapidDataMapper cooperate with the framework of choice and to blend into the native framework environment. Included files can be libraries, conversion scripts, replacement files etc.

Currently, the following frameworks are officially supported by RapidDataMapper:

Latest

The cutting edge version of RapidDataMapper is always available from GitHub.com. It does only contain the library files, Docbook sources, tests and framework compatibility files. It does not contain a rendered manual nor is it guaranteed to work, so use it at your own risk.

Manual

The manual covers almost all aspects of using RapidDataMapper and it also contains framework specific instructions, to make RapidDataMapper easy to use with tools you already know. The manual comes in two versions, one in a single HTML file and the other as multiple HTML files.

Versions

Blog

06

apr

2010

Version 0.6.1

Mainly a bugfix release, but it has got a nice new method for dumping objects: Db::dump.

0.6.1 Change Log

25

feb

2010

Version 0.6 has been released

Check out the change log for information about the new features: 0.6 Change Log.

5

feb

2010

ON DELETE CASCADE and ON DELETE RESTRICT implemented

I've finally managed to port the code I made last summer for the ON DELETE CASCADE action. The code I wrote before the rewrite did not really match too well with the new relationship system, so it took a bit longer to assemble but finally I arrived on a solution that seems to be working.

Note that I wrote SEEMS to be working, I have not made any functional tests for the new feature, so I cannot guarantee that it will work properly. I have tested it during development, and I plan to write some functional tests for it (and the rest of RDM) soon.

To use the ON DELETE RESTRICT and ON DELETE CASCADE settings, check out Db_Descriptor_Relation->setOnDeleteAction() in the manual.

Anyway, it seems to be working pretty good, and it also takes both the settings into account when performing a cascade:

  1. Check for related rows which restrict deletion (ON DELETE RESTRICT).
    If found, return false.
  2. Check for related rows marked with CASCADE.
    If found go to 1, but with the new related data, then move to 3 if we don't get false.
  3. Delete rows.
  4. Return true.

The new code can be found on github, as usual.

5

jan

2010

Transaction support implemented

Transactions has now been implemented in the development version (can be fetched from github).

It does not support nesting of transactions, because many RDBMs does not allow it or its implementation differs a lot.

New methods:

  • Db_Connection->transactionStart();
  • Db_Connection->transactionCommit();
  • Db_Connection->transactionRollback();

Example:

$db = Db::getConnection();

try
{
    $db->transactionStart();
    
    // Do stuff:
    $db->query(...);
    
    $db->transactionCommit();
}
catch(Exception $e)
{
    $db->transactionRollback();
    
    // Let other parts handle it
    throw $e;
}

The Db_Connection->query method throws exceptions on failed queries, which means that it is easy to detect and rollback.

15

dec

2009

Version 0.5.1 released

I have now released version 0.5.1 which contains the following:

  • Specialized Db_MapperQuery->count which makes counting objects when joining related objects produce an accurate count.
  • Methods for filtering with IS NULL and IS NOT NULL.
  • Increased performance of Db::isChanged.
  • Bug fixes:
    • Faulty instance checking code generated by Has One relationships.
    • Malfunctioning database prefix in ORM queries.
    • Fixed broken Db::related method.
  • Updates to the manual:
      Added documentation for Db_MapperQuery->count and Db::isChanged.

15

dec

2009

RapidDataMapper without separate models

RapidDataMapper does not provide any model functionality whatsoever, instead this is expected to be provided by the user or the framework. (It provides query building, but that is not really the same, models should contain methods which return finished objects or almost-finished queries, IMHO) It might not always be beneficial to have to place the model somewhere else than where the data objects are stored, so I will show you a simple way to integrate the model into the data object.

If you've read the manual you probably already know that the data objects are completely decoupled from the mappers and the mapper and database–interaction code in general. This makes it optimal to use static methods located on the data objects which substitutes the model.

And for all of you out there who uses CodeIgniter, you won't need to load the models with this trick, instead will the MY_Loader autoload the data object, which also happens to be the model, when it is requested.

Note: This is only suitable in smaller projects where the models won't be used by several components, need settings or (model)object instances.

Example:

class Track
{
    // properties here
    
    /**
     * A simple fetcher, not strictly needed.
     */
    public static function get($id)
    {
        return Db::find('track', $id);
    }
    /**
     * Create a query for fetching a track with its album and artist.
     */
    public static function get_w_artist_album()
    {
        return Db::find('track')->related('artist')->related('album');
    }
}

 

Example usage:

$t = Track::get(5);

// do something

Db::save($t);

$tracks = Track::get_w_artist_album()->orderBy('date_played', 'desc')->limit(20)->get();

foreach($tracks as $t)
{
    echo "{$t->artist->name} - {$t->album->name} - {$t->name}";
}

 

You can also add instance methods which call Db::save() or Db::delete() which might be beneficial if you want your interaction with the object to remind of the ActiveRecord pattern:

class Track
{
    public function save()
    {
        return Db::save($this);
    }
    public function delete()
    {
        return Db::delete($this);
    }
}

 

PS. For all you who wonder why I don't use a CMS / blog software for this site; I will create one (or improve Ionize, because I had some performance issues when trying it out) as soon as I have the time.

13

dec

2009

RapidDataMapper 0.5 has been released!

After a lot of work during the last half of a year, RapidDataMapper have finally reached a state where I can release it to the public. It was not easy, but I hope that the effort is worth it as I think RapidDataMapper really is a promising project.

Version 0.5 is lacking a lot of the features that I have planned for 1.0, but it has enough features to be used in many of the common tasks, and I deem it worthy for production (but nothing extremely mission critical or in need of performance, as it is not tested enough and is missing support for query caching and transactions).

The manual has not gone through proofreading, so it might contain factual errors and it surely is neither optimally structured nor correct in its language. If you find any problems or errors, please contact me (http://github.com/m4rw3r).

To start reading the manual, check out the manual section.

I hope you will find this project useful, and if you have the time and motivation, hope that you will post suggestions or contribute something.

Thanks to:

  • Christophe, from Too Pixel, Webdesign in Geneva, for providing me with support for the project and hosting.
  • Michel-Ange and his brother for the nice logo.