Ci siamo fermati dopo aver illustrato Propel e Creole, rispettivamente l’ORM Layer e l’Abstraction Layer integrati in Symfony, e le configurazioni di connessione ad un determinato DBMS. Ora ci occuperemo della creazione del Data Model e della generazione dell’Object Model.
creazione del Data Model
Il Data Model rappresenta la struttura dei dati all’interno del nostro DB e guiderà la generazione dell’Object Model. Symfony ci consente di seguire varie strade per la creazione del Data Model:
- Partendo dal DB;
- Utilizzando un file XML
- Utilizzando un file YML
Creazione dal DB
Abbiamo già a disposizione la nostra bella base dati? Allora possiamo attingere ad essa per la creazione del Data Model. Come passi preliminari dobbiamo ricordarci di editare il file project/config/propel.ini per inserire le impostazioni di connessione al DB come segue:
propel.database.url=mysql://db_user:db_pass@localhost/db_name
fatto questo sul terminale nella cartella del progetto possiamo lanciare il comando symfony:
> symfony propel-build-schema
il comando genererà un file XML che verrà salvato in project/config/schema.xml questo file sarà utilizzato dal Layer ORM per generare l’Object Model corrispondente.
Creazione del data model su file XML
Un altro modo di generare il Data Model è descrivendolo con una sintassi XML riconosciuta da Propel. La sintassi non è complessa e ve ne fornirò un esempio tratto dal Symfony Book:
<?xml version="1.0" encoding="UTF-8"?> <database name="propel" defaultIdMethod="native" noXsd="true" package="lib.model"> <table name="blog_article" phpName="Article"> <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" /> <column name="title" type="varchar" size="255" /> <column name="content" type="longvarchar" /> <column name="created_at" type="timestamp" /> </table> <table name="blog_comment" phpName="Comment"> <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" /> <column name="article_id" type="integer" /> <foreign-key foreignTable="blog_article"> <reference local="article_id" foreign="id"/> </foreign-key> <column name="author" type="varchar" size="255" /> <column name="content" type="longvarchar" /> <column name="created_at" type="timestamp" /> </table> </database>
Questo file XML ci consentirà di generare L’Object Model, ma anche di creare la struttura del nostro DB poiche symfony tramite Propel è in grado di tradurlo in SQL che potremo dare in pasto al nostro DBMS.
Creazione del data model su file YML
Un altro modo di generare il Data Model è descrivendolo con una sintassi YAML. La sintassi YAML (file .yml) per descrivere il Data Model non è riconosciuta nativamente da Propel, ma è propria di Symfony, perciò quando eseguiremo da terminale una chiamata a propel-build-sql, Symfony si occuperà di tradurre questo file YML in XML (generated-schema.xml) cioè il formato di file atteso da Propel. Ricorrere alla sintassi YML facilita la lettura e la comprensione del Data Model, inoltre Symfony ha delle regole di presunzione sul nome dei campi e sui loro attributi che accelerano la scrittura del Data Model. Di converso, non è possibile specificare Data Model complessi, per i quali offre maggiore flessibilita la sintassi XML (vedi Propel Doc). Di seguito trovate la sintassi YML che descrive lo stesso Data Model del precedente XML:
propel:
blog_article:
_attributes: { phpName: Article }
id:
title: varchar(255)
content: longvarchar
created_at:
blog_comment:
_attributes: { phpName: Comment }
id:
article_id:
author: varchar(255)
content: longvarchar
created_at:
Generazione del codice SQL e import nel DBMS
Dando per scontato di avere già creato il DB e di aver attribuito i corretti permessi di accesso, non ci resta che eseguire nell terminale dalla cartella di progetto i task symfony per generare il codice SQL che rappresenta la struttura del nostro DB e darlo poi in pasto al nostro DBMS affinchè lo esegua. Il codice SQL generato tramite i seguenti tasks e ovviamente compliant con il nostro DBMS engine specificato nel nostro file propel.ini
> symfony propel-build-sql (ver. 1.0)
> symfony propel:build-sql (ver. 1.1 +)
> mysql -u db_user -p db_name < data/sql/schema.sql
Object Model
Ok fin qui tutto bene, ora generiamo dal Data Model il nostro object model con tutte le classi necessarie al layer ORM. Sempre nel nostro terminale dalla cartella di progetto lanciamo:
> symfony propel-build-model (ver. 1.0)
> symfony propel:build-model (ver. 1.1 +)
Il risultato è l’analisi dello schema che rappresenta il Data Model e la generazione di 4 object classes per ogni tabella del Data Model. Rispetto allo schema illustrato in precedenza avremo:
nella cartella project/lib/model/om:
- BaseArticle.php
- BaseArticlePeer.php
- BaseComment.php
- BaseCommentPeer.php
nella cartella project/lib/model:
- Article.php
- ArticlePeer.php
- Comment.php
- CommentPeer.php
Classi Base e Custom
Le classi “Base” sono quelle generate dal Layer ORM e vengono ricreate ogni volta che il comando symfony propel:build-model viene eseguito, cioè ogni volta si abbia la necessità di ricostruire l’Object Model per un cambiamento del Data Model (aggiunta/rimozione di colonne, aggiunta/rimozione di tabelle etc.). Proprio per questa ragione queste classi “Base” non devono mai essere modificate. Per aggiungere funzionalità all’Object Model dovremo operare sui file della cartella project/lib/model detti Custom Classes che ereditano dalle Base Classes e le possono estendere con l’aggiunta o la modifica di metodi.
Classi Object e Peer
Le classi “Article” e “Comment” sono object classes e rappresentano i record del DB. Le classi “Peer” invece sono Peer Classes (ma va?) e implementano metodi statici per operare sulle tabelle e per recuperare i record da esse. Questi metodi restituiscono oggetti della relativa object class, ad esempio:
$articolo = ArticlePeer::retrieveByPk(13);
$articolo è l’oggetto della classe Article restituito dal metodo retrieveByPk() della classe ArticlePeer.
Non possono esistere oggetti per le classi Peer ecco perchè i metodi sono invocati tramite l’operatore :: invece che tramite il consueto operatore ->