Object Modeling Framework (OMF), a framework for handling objects and relationships. Available for pure PHP and Yii Framework. Portable to other languages (comming soon).
OMF is a little but powerful framework capable of handling the persistence for objects and relationships independent of the selected storage mode. All your system can be built using OMF, including the relationships between your business classes.
Suppose you have a CAR, a PIECE and a PERSON as example of business classes. Now explore the possible relationships between that classes: A Car has Pieces, that last ones can be sold by a Person, and again, a Person can be the owner of that Car or the technician for that same Car. In Omf this example can be draw as this:
[:Car]--{has_piece}-->[:Piece]
[:Person]--{is_owner}-->[:Car]
[:Person]--{tech_guy}-->[:Car]
[:Person]--{is_vendor}-->[:Piece]
In traditional persistence models you need at least 6 or 7 tables to persist this model, when system grows in size then the number of tables grows too. Using OMF you will always has 2 tables: omf_objects and omf_relationships, no more.
In OMF the portability is a core part of this framework. Suppose again you have a big system having 150 tables composing the persistence, now due to something you must move your system to a Cloud or somewhere else. What happen with that 150 tables, indexes and all the stuff ? Or think about the changes required to that persistence model after any change in your source code ?. In OMF that's not a problem at all because you store all your system in two tables, the way in how your system read/write relay on a simple persistence php file.
In my experience using OMF as core component for persistence and object-relationship handling all becomes fluid and beauty, after core changes in source code (new features, bug fixes etc) i never again be concerned of what needs to be done in respect to sql changes because OMF will not change, it still be the same: two tables.
/*
[:Person]--{is_owner}-->[:Car]
[:Car]--{has_piece}-->[:Piece]
[:Person]--{tech_guy}-->[:Car]
[:Person]--{is_vendor}-->[:Piece]
*/
$api = new OmfDb();
//
// 1. create the core objects:
//
list($nova) = $api->create("Car");
list($jhon) = $api->create("Person");
list($peter) = $api->create("Person");
list($kelly) = $api->create("Person");
list($carburator) = $api->create("Piece");
list($doorlocker) = $api->create("Piece");
// create some sample attributes
$api->set($nova, "mark","Chevrolet");
$api->set($nova, "model","Nova 74");
$api->set($nova, "VIM","12345678");
$api->set($jhon, "firstname","Jhonn");
$api->set($jhon, "lastname","Doe");
$api->set($carburator, "invoice_id","123");
$api->set($doorlocker, "invoice_id","456");
//
// 2. create the relationships between objects:
//
$api->createRelation($jhon, $nova, "is_owner");
$api->createRelation($peter, $nova, "tech_guy");
$api->createRelation($kelly, $carburator, "is_vendor");
$api->createRelation($kelly, $doorlocker, "is_vendor");
$api->createRelation($nova, $carburator, "has_piece");
$api->createRelation($nova, $doorlocker, "has_piece");
$api->createRelation($jhon, $nova, "owns_by");
$api->createRelation($peter, $nova, "is_tech_guy");
$api->createRelation($kelly, $nova, "is_car_vendor");
$api->createRelation($peter, $nova, "support_guy");
$api->createRelation($kelly, $nova, "support_guy");
Ok, now you know how OMF create the objects and its relationships, now a little example to show how to read the information, lets starting by finding a car by its VIM number: (the VIM is an attribute given to this example, is the legal Vehicle Identification Number in the United States, is not a core part in OMF at all...)
//
// 3. query the system in various ways
//
$api = new OmfDb();
$car_attributes = $api->getObject('Car',array('VIM'=>'1234567'));
$car_id = $car_attributes["id"]; // "a unique id created by the framework"
$car_mark = $car_attributes["mark"]; // "Chevrolet"
$car_model = $car_attributes["model"]; // "Nova"
// who is given support to this car ?
//
foreach($api->getParents($car_id, "support_guy") as $obj){
// getParents retrieve those objects having the relationship named "support_guy"
// pointing to this car. you can query any relationship name.
list($obj_id) = $obj;
$who_is_given_support = $api->get($obj_id, "firstname");
}
// what pieces has this car ? and who is the vendor of that piece ?
//
foreach($api->getChilds($car_id, "has_piece") as $obj){
// getChilds retrieve those objects having the relationship named "support_guy"
// having this car as parent.
list($piece_id) = $obj;
$invoice_id = $api->get($piece_id, "invoice_id");
// now query the vendor of that piece:
foreach($api->getChilds($piece_id, "is_vendor") as $obj2){
list($person_id) = $obj2;
$vendor_name = $api->get($person_id, "firstname"); // Kelly
}
}
This little example becomes complicated and heavy in traditional persistence models, in OMF is Easy to understand, and persistence is not a problem at all: all this system is stored in two unique tables: omf_objects and omf_relations.
You can see in the above example this line: "$api = new OmfDb;". This is very important and becomes part of what i call: "the omf portability". This $api instance is targeting a traditional database (table based) for storing the objects. By creating a new class implementing the required software interfaces then you can move your entire system to a different persistence model without make any change to your business logic. By default OMF becomes ready with a class named OmfDb ready to be used and designed to persist objects in two tables: omf_objects and omf_relations, this two tables are required by this class (OmfDb) and are not part of the OMF core.
Check the README.md for more detailed api examples.