Hi Marcelo
ORM are a very elegant solution followed widely in almost every modern programming language. The most important concept behind is that it separates the
persistency layer from the
data layer, that is it's hidden to the app how the data is stored in permanent memory. For those of us who have being using dbfs for so long, it could be a little bit challenging to forget about that. We are so used to the navigational ISAM model, GOing TOP, SKIPing until EOF that all that sounds a little bit weird in the begining.
Back to ORM, the most complete ones have 2 types of objects: the Entity object and the Repository object. The Entity represents one and only one individual of the collection: a customer, a product, an account, etc. The Repository is the full set of objects on a given Entity, like ClientsRepository, ProductRepository, etc. The Repository is usually the responsible for Find()ing a given or a subset of entities, and for the aggregational functions like Count(), Sum(), etc.
Entities are also able to represent complex objects throw the knowledge of relations between entities: an Invoice:hasMany(InvoiceItems), an Invoice:belongsTo(Customer) and so on, so in your code, given an instance of Invoice oInvoice, you can get the corresponding oCustomer just calling oInvoice:Customer.
Usually the reciprocal relation is true: an Invoice:belongsTo(Customer) so a Customer:hasMany(Invoice) .
With such ORM the code will reduce the need of direct data access by our code significantly.
This is a sample of an Entity written in PHP and Laravel's Eloquent ORM
- Code: Select all Expand view
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Cliente extends Model
{
protected $fillable = [
'agrupacion_id',
'nombre',
'apellido1',
'apellido2',
'cif',
'tipo_persona',
'tipo_via',
'nombre_via',
'num_via',
'otros_via',
'poblacion',
'codigo_postal',
'telefono1',
'telefono2',
'email',
'fax',
];
static function rules(){
return [
'nombre' => 'required|max:64',
'apellido1' => 'max:45',
'apellido2' => 'max:45',
'cif' => 'required|cif_nif_nie',
'tipo_persona' => 'required|in:F,J',
'tipo_via' => 'required',
'nombre_via' => 'required',
'num_via' => 'required',
'otros_via' => '',
'poblacion' => '',
'codigo_postal' => 'required',
'email' => 'email|required|max:64',
];
}
public function bancos(){
return $this->hasMany('App\Models\BancoCliente', 'cliente_id', 'id');
}
public function solicitudes(){
return $this->hasMany('App\Models\Solicitud', 'cliente_id', 'id');
}
public function agrupacion(){
return $this->belongsTo('App\Models\Agrupacion', 'id', 'agrupacion_id');
}
/**
* List of values for field Tipo de Persona
*
* @return array
*/
static public function tipo_personaSelectData(){
return [
'J' => 'Jurídica',
'F' => 'Física',
];
}
}
$Fillable are the fields the app is able to change, rules are the validation rules to apply in creating or editing, and then bancos, solicitudes and agrupacion are the relations among entities, so given a Client $client, invoking $client->bancos will return a collection of bank accounts without the need of writing a single line of code or SQL. Beauty! Thanks to the static methods, the same Model class acts as a Repository, so Cliente::find(32) will retrieve the cliente whose id is 32.
All of this can be done independent of the database used: it can be MySQL/MariadB, Postgress, SQLServer, Oracle, Sqlite, etc.
It would be really nice to have an ORM like that in Harbour, and it will have to be really good to make us to forget about the simplicity of having the dbf data as part of the very same language. I think there is no equivalent of that in any other language in the world.