Welcome Guest, Not a member yet? Register   Sign In
RapidDataMapper, a new Object-Relational-Mapper


I've finally managed to get my new Object-Relational-Mapper to a stage where I can release it to the public. It has taken a long time, but finally I also have a complete? manual ready (over 26k words, it was a bit of a pain to write).

RapidDataMapper is both a stand alone Object-Relational-Mapper and a mapper which can be integrated into different frameworks. I have made it CodeIgniter-compatible as a first step, but other frameworks will also follow (when I or someone else has time to create compatibility files, making it officially compatible).

The CodeIgniter specific variant replaces the $this->db object with the main connection object of RapidDataMapper, this to make it easier to use. But you can also skip replacing it (by modding the supplied MY_Loader.php) if you want to be able to use both simultaneously.

RapidDataMapper is based on the DataMapper pattern, and I have taken this to the "extreme" by completely decoupling the objects from the mapper and hiding the mappers behind a proxy object. Compared to IgnitedRecord (my previous ORM), RapidDataMapper does not affect the model, at all. Instead the model is supposed to do what it always has done: fetching and storing data. RapidDataMapper is a tool which is to be used *by* the model to simplify database interaction (it is not strictly so, you can use it in the controller or even in the view, but it "makes more sense" to place all db interaction in a few select files).

A somewhat new idea which I use in RapidDataMapper is the Descriptors. They are objects which describe how the objects should be mapped to the database, which columns that map to properties etc. They can be extended and modified in innumerable ways, making it possible to create your own defaults and override normal behaviour of the mappers.

RapidDataMapper uses an autoloader to load the files, and they are stored in the directory application/data_model/ with the name of the class + .php.

Example usage:
// application/data_model/user_obj.php
class User_obj
    public $name;
    public $id;

// application/data_model/user_objdescriptor.php
class User_objDescriptor extends Db_Descriptor
    function __construct()
         $this->setSingular('user'); // this makes the other default adjust themselves, eg. table becomes users


// Usage:

$u = new User_obj();    // the User_obj class is autoloaded

$u->name = 'Martin';

Db::save($u);    // here is the "magic" done

echo $u->id;

$u = Db::find('User_obj', 1);

echo $u->name;
That was just a very very simple example of the usage of RapidDataMapper, it is capable of a lot more.

RapidDataMapper is extremely configurable but it is still aimed to be easy: It assumes a lot of defaults but you can replace almost any of them. By using a code builder and mapper cache can RapidDataMapper really be rapid: only a few files needs to be loaded once the mapper has been built.

Suggestions and comments are extremely welcome!
(and I'm happy to help people start with it, but check the manual first, it should cover the most of it)

Link: http://www.rapiddatamapper.com


First to comment!

If Rapid Datamapper makes it big, my name will be in the hall of fame.

Now, lets go test this shiny new library out.

[eluser]Johan André[/eluser]
You really put alot of work into this!

I have'nt been able to try it, but I read the docs and it looks awesome!

Good work!

Just had a go and this looks REALLLY nice. Great work! Just wondering why you chose to create a new folder called data_model and not put the models in the models folder? And on the same note not use the system/cache folder to cache the models too?

Is that because you want it to not be codeigniter specific? Perhpas in that case you could add some configuration settings that would allow you to set the path to those locations.

Also noticed that the autoload doesn't seem to work when you do a find(). For example

This autoloads the track model and descriptor
$t = new Track();

However using this line doesn't trigger the autoload
$tracks = Db::find('track');

I get the following error
Fatal error:  Uncaught exception 'Db_DescriptorException' with message 'RapidDataMapper: Descriptor for class "track": Descriptor is missing.' in /Applications/MAMP/htdocs/CodeIgniter_1.7.2/system/application/libraries/Db.php:364
Stack trace:
#0 /Applications/MAMP/htdocs/CodeIgniter_1.7.2/system/application/libraries/Db.php(397): Db::getDescriptor('track')
#1 /Applications/MAMP/htdocs/CodeIgniter_1.7.2/system/application/libraries/Db.php(494): Db::getMapper('track')
#2 /Applications/MAMP/htdocs/CodeIgniter_1.7.2/system/application/controllers/welcome.php(16): Db::find('track')
#3 /Applications/MAMP/htdocs/CodeIgniter_1.7.2/system/codeigniter/CodeIgniter.php(236): Welcome->index()
#4 /Applications/MAMP/htdocs/CodeIgniter_1.7.2/index.php(115): require_once('/Applications/M...')
#5 {main}
  thrown in /Applications/MAMP/htdocs/CodeIgniter_1.7.2/system/application/libraries/Db.php on line 364

I like this alot. I'm one of your die hard ignitedrecord fans. Obviously I understand the benefits of the separation of the object model from the interaction methods, and I especially like the fact that you have abstracted this one step further (away from codeigniter). However I have become quite attached to the methods and code names that are used by both codeigniter active record and also ignitedrecord. Why have you chosen to change little things like 'order_by' to 'orderBy'?

Also would be keen to see some tests to compare Ignitedrecord vs RDM in both speed and memory!

Anyway sorry to blab on! Once again great work!


Thanks for the appreciation!


First: The data objects are not models, they are usually just data containers with some convenience methods for application specific tasks, eg. generating an image path.
But you can make them into whatever you like (you can even make them into some kind of ActiveRecord-ish data object, but that might not really be optimal Tongue ).

So the reason they aren't stored in app/models is that they do not behave like CI models. Unless you make them so, but that would require a lot of unnecessary code compared to when you just have create a normal CI model which uses the data objects.

Second: And the reason I use an app specific mapper cache: What would happen if you share the mapper cache between two apps and they have different settings for the same class name?

Third: The reason you get that error is because RapidDataMapper cannot find the descriptor, it may be because the CI specific autoloader (MY_Loader::load_data_object, added in My_Loader::initRDM) is not loaded (or it can also be so that the class name is not correctly spelled (and the filename should be lowercase, but that won't matter on mac)).

Four: The reason I changed from underscore_separated_methods to camelCaseMethods is that a lot of other PHP projects prefer to use camelCase. I still use underscore_separated_variable_names, but that is only internally in the classes. Another reason is that it requires less keystrokes to write.

About the models, I've written about an alternative to CI's models if you don't want to use them while using RapidDataMapper.

The post can be found here: http://www.rapiddatamapper.com/#blog

And about that performance comparison, what type of tests do you want me to do?

Has anyone tested RapidDataMapper with a somewhat advanced configuration (ie. more than one mapped class)?
(Just curious, and no, I haven't found a fatal flaw Tongue)

Or is it that:

a) Everyone is preparing for Christmas?
b) My library is missing a feature you must have?
c) The manual is too large?
d) The manual sucks?


Did you get it to work?

Yeah just been really busy (and the snow was calling me too) but I did have another play around with it. I found I was rebuilding the functionality of Ignitedrecord using RDM. Is that the idea? Do I create a model that interacts with the data model on top of RDM? You mentioned on your website that you have not yet finished implementing all of the features. I'm keen to see your todo list..

Nope I didn't fix that error.

I put the 'track' model and the 'trackDescriptor' all in the one file 'track.php' and put it in the 'data_model' folder. I then tried to put the trackDescription into its own file 'trackDescriptor.php' in the same folder and that didn't fix the problem. I guess i'm not perfectly clear (even from your examples in the manual) on exactly what files to create and where to put them. You say what to put in them but not where and how.

Theme © iAndrew 2016 - Forum software by © MyBB