Skip navigation

Salut à toutes et à tous,

Ce petit billet pour vous présenter la transformation d’un modèle en code, ou plus simplement, la génération de code au travers d’un modèle.

Dans l’état de l’art du développement logiciel, on fait abstraction du code en créant des « templates », ou en bon vieux français, des « patrons » ou encore des « modèles » :-)
Cela nécessite donc qu’un template se réfère, dans sa terminologie, à un modèle pour injecter les données.

Je vais ici utiliser le méta-modèle défini dans mon précédent billet ainsi que le modèle et l’outillage réalisé à titre d’exemple.

L’objectif est d’utiliser ce modèle

Simple modèle d'exemple

Pour générer un fichier YAML correspondant à ceci (dans sa forme et non ses données):

Produit:
..columns:
….name: { type: string(255), notnull: true, unique: true }
..relations:
….Categories: { class: Categorie, foreignAlias: Produits, refClass: ProduitCategorie, local: produit_id, foreign: categorie_id }

Categorie:
..columns:
….name: { type: string(255), notnull: true, unique: true }
..relations:
…. Produit: { class:Produit, foreignAlias: Categories, refClass: ProduitCategorie, local: categorie_id, foreign: produit_id }

ProduitCategorie:
..columns:
….produit_id: { type: integer(20), primary: true }
….categorie_id: { type: integer(20), primary: true }
..relations:
….Produit: { local: produit_id, foreign: id, foreignAlias: Produits }
….Categorie: { local: categorie_id, foreign: id, foreignAlias: Categories }

. représente ici un espace, tant les espaces sont importants dans les fichiers yaml.

Voici le code du programme de génération :

[%
var m : Model := Model.allInstances().at(0);

for( class in m.defines )
{
%]
[%=class.name%]:
[%
if( class.column.size() > 0 ) { %]
..columns:
[% for( column in class.column ) { %]
….[%=column.name%]: { [%=column.generateProperties()%] }
[% }
}
if( class.relation.size() > 0 ) { %]
..relations:
[% for( relation in class.relation ) { %]
….[%=relation.name%]: { [%=relation.generateProperties()%] }
[% }
}
%]

[%
}

operation OneToOne generateProperties() : String {
return ‘local: ‘ + self.relates.name.toLowerCase()+’_id’ + ‘, foreign: id, foreignAlias: ‘ + self.relates.generateSingularName();
}

operation OneToMany generateProperties() : String {
return ‘otm'; –je vous laisse vous amuser
}

operation ManyToMany generateProperties() : String {
return ‘class : ‘ + self.relates.name + ‘, foreignAlias: ‘ + self.owner.generateSingularName() + ‘, refClass: ‘ + self.refClass.name + ‘, local: ‘ + self.owner.name.toLowerCase+’_id’ + ‘, foreign: ‘ + self.relates.name.toLowerCase+’_id';
}

operation Column generateProperties() : String {
return ‘type: ‘+ self.type.generateTypeName()+'(‘+self.type.max+’)’ + ‘, primary: ‘ + self.primary + ‘, notnull: ‘ + self.generateIsNull() + ‘, unique: ‘ + self.generateIsUnique();
}

operation Column generateIsUnique() : String {
return self.unique;
}

operation Column generateIsNull() : String {
return self.notnull;
}

operation Type generateTypeName() : String {
if(self.isTypeOf(sfDoctrine!Integer)){ return ‘integer'; }
}

operation Class generateSingularName () : String {
return self.name;
}
%]

Et voici le résultat généré dans un fichier gen_schema.yml (il faut configurer un lanceur pour exécuter la génération, le site d’Epsilon explique ça très bien, voir les newsgroup aussi) :

Produit:
..columns:
….id: { type: integer(20), primary: true, notnull: true, unique: true }
..relations:
….Categories: { class : Categorie, foreignAlias: Produit, refClass: ProduitCategorie, local: produit_id, foreign: categorie_id }

Categorie:
..columns:
….id: { type: integer(20), primary: true, notnull: true, unique: true }
..relations:
….Produits: { class : Produit, foreignAlias: Categorie, refClass: ProduitCategorie, local: categorie_id, foreign: produit_id }

ProduitCategorie:
..columns:
..categorie_id: { type: integer(20), primary: true, notnull: true, unique: false }
….produit_id: { type: integer(20), primary: true, notnull: true, unique: false }
..relations:
….Categorie: { local: categorie_id, foreign: id, foreignAlias: Categorie }
….Produit: { local: produit_id, foreign: id, foreignAlias: Produit }

N.B.: il y a quelques différences du fait de modifications entre temps (pluriel/singulier, etc), mais on fait ce qu’on veut en tout point, ne vous concentrez donc pas sur les incohérences entre mes deux billets, ce n’est qu’un exemple réalisé en deux temps ;-)

About these ads

Laisser un commentaire

Choisissez une méthode de connexion pour poster votre commentaire:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

Suivre

Recevez les nouvelles publications par mail.

%d blogueurs aiment cette page :