mercoledì 30 settembre 2009

symfony, creazione schema database (schema.yml)

A partire dalle specifiche iniziali dell'applicazione viste in precedenza, iniziamo a lavorare sul modello dati di Lyra.

Attivazione Doctrine

L'applicazione utilizzerà Doctrine come ORM quindi è necessario attivare il relativo plugin in config/ProjectConfiguration.class.php

public function setup()
{
  $this->enablePlugins(array('sfDoctrinePlugin'));
  $this->disablePlugins(array('sfPropelPlugin'));
}

Occorre poi pulire la cache di symfony con

./symfony cc

Poiché abbiamo abilitato un nuovo plugin bisogna utilizzare il comando plugin:publish-assets per consentire l'installazione di eventuali file accessori (immagini, css, javascript) necessari al funzionamento del plugin.

./symfony plugin:publish-assets

Infine è bene rimuovere ogni riferimento a Propel (l'ORM alternativo a Doctrine) che non sarà utilizzato.

rm web/sfPropelPlugin
rm config/propel.ini
rm config/schema.yml

Creazione dello schema del database

In symfony la struttura delle tabelle necessarie all'applicazione viene definita in un file in formato YAML (schema.yml). Per maggiori dettagli su questo formato si può consultare il sito ufficiale (http://yaml.org/).

Si tratta comunque di un formato abbastanza intuitivo e non difficile da utilizzare una volta visti alcuni esempi.

Il file schema.yml deve essere collocato in una cartella config/doctrine che va creata

mkdir config/doctrine

Le tabelle necessarie per questa versione preliminare di Lyra sono:

  • Tipi di contenuto
  • Articoli
  • Commenti
  • Cataloghi
  • Etichette

Non è possibile fare adesso un esame dettagliato del file schema.yml. La versione completa può essere scaricata da Google Code. Inoltre tutti i dettagli sulla struttura dei file sono disponibili sulla documentazione ufficiale di symfony.

config/doctrine/schema.yml
  
  LyraArticle:
    tableName: articles

LyraArticle è il nome della classe autogenerata da Doctrine che, come si vedrà, utilizzeremo per gestire i record della tabella articoli, articles è il nome della tabella sul database.

actAs:
    Timestampable: ~
    Sluggable:
      fields: [title]
      canUpdate: true
      unique: true
      indexName: article_slug

actAs indica una serie di comportamenti predefiniti del modello implementati da Doctrine senza che si debba scrivere codice.

Timestampable

Alla tabella verranno aggiunti due campi created_at, updated_at che saranno mantenuti automaticamente aggiornati con la data di creazione e di ultima modifica del record.

Sluggable

Alla tabella verrà aggiunto un campo slug con lo stesso contenuto del campo title modificato in questo modo:

  • gli spazi sono trasformati in '-';
  • i caratteri diversi da lettere e numeri sono rimossi;
  • i caratteri maiuscoli sono trasformati in minuscoli;
  • i caratteri accentati sono convertiti nell'equivalente non accentato.

Se ad esempio il campo title di un record contiene

Però che bell'articolo

il campo slug conterrà

pero-che-bell-articolo

In questo modo il campo slug può essere utilizzato per generare le URL SEF. canUpdate impostato a true consente la modifica da parte dell'utente del campo generato automaticamente, unique impostato a true indica che il campo deve essere univoco nella tabella: se due articoli hanno lo stesso identico titolo, sarà utilizzato un suffisso numerico progressivo nello slug per differenziarli. Con indexName indichiamo il nome da dare all'indice sul campo slug.

options:
    collate: utf8_unicode_ci
    charset: utf8

Impostiamo set di caratteri e collazione in utf-8.

columns:
    id:
      type: integer(4)
      primary: true
      autoincrement: true
    title:
      type: string(255)
      notnull: true
...

In columns definiamo i campi della tabella. Con primary e autoincrement a true indichiamo che il campo id sarà la chiave primaria autoincrementante della tabella, con type impostiamo il tipo del campo. Nello schema si utilizzano tipi indipendenti dal database utilizzato. Al momento della generazione degli script SQL per la creazione delle tabelle, sarà Doctrine a convertire questi tipi in quelli corrispondenti al particolare database scelto.

Ecco le corrispondenze tra i tipi di dato Doctrine utilizzati nello schema che stiamo esaminando e tipi MySQL:

DoctrineMySql
integer(1)tinyint
integer(4)int
booleantinyint(1)
cloblongtext
clob(65532)text
timestampdatetime

Per quanto riguarda i tipi di dato string, se la lunghezza è inferiore o uguale a 255 corripondono al tipo MySQL varchar della stessa lunghezza, se la lunghezza è superiore a 255 corrispondono a text, mediumtext o longtext.

Ometto i campi rimanenti della tabella Articoli e passo alla tabella Commenti soffermandomi però solo sulla parte più significativa.

LyraComment:
...

columns:
    id:
      type: integer(4)
      primary: true
      autoincrement: true
    article_id:
      type: integer(4)
...
relations:
    CommentArticle:
      class: LyraArticle
      local: article_id
      foreign: id
      foreignAlias: ArticleComments
      onDelete: CASCADE

Nello schema dobbiamo anche definire le relazioni tra tabelle, in questo caso la relazione uno a molti tra la tabella Articoli e la tabella Commenti:

  • class: nome della classe della tabella correlata (Articoli);
  • local: nome del campo di relazione nella tabella locale (Commenti);
  • foreign: nome del campo di relazione nella tabella correlata;
  • foreignAlias: nome della relazione vista 'dall'altro lato', cioè da quello della tabella Articoli. Vedremo in seguito a cosa serve;
  • onDelete: impostato su CASCADE determina la cancellazione automatica dei commenti quando il record correlato in Articoli viene cancellato.

Nella parte restante del file schema.yml si trova anche un esempio di come definire una relazione molti a molti, quella tra gli Articoli e le Etichette.

Vedremo la prossima volta come a partire dallo schema saranno generate le classi del Modello e gli script SQL per la creazione delle tabelle.

Ho eseguito il commit della revisione 5 su Google Code.

Nessun commento:

Posta un commento

Nota. Solo i membri di questo blog possono postare un commento.