Coat::Persistent at FPW2009
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

Coat::Persistent at FPW2009

  • 2,373 views
Uploaded on

Coat::Persistent est un ORM écrit pour Perl en s'inspirant de l'API d'ActiveRecord de Rails. Cette présentation a été tenue aux journées Perl 2009

Coat::Persistent est un ORM écrit pour Perl en s'inspirant de l'API d'ActiveRecord de Rails. Cette présentation a été tenue aux journées Perl 2009

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
2,373
On Slideshare
2,275
From Embeds
98
Number of Embeds
3

Actions

Shares
Downloads
5
Comments
0
Likes
0

Embeds 98

http://www.sukria.net 96
http://www.slideshare.net 1
http://www.slideee.com 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Coat::Persistent Votre base de données à portées d'objets FPW 2009 – 13 Juin 2009 Alexis Sukrieh http://www.sukria.net
  • 2. Plan
    • Le concept ORM
    • 3. Origines de Coat::Persistent
    • 4. Mise en place de Coat::Persistent
    • 5. Accèder aux données (lecture/écriture)
    • 6. Relations entre tables / modèles
    • 7. Fonctionnement du cache
  • 8. Le concept ORM Une méthode moderne et efficace pour manipuler les données
  • 9. Le principe ORM
    • Un framework Objet
    • 10. Une table devient une classe
    • 11. Une ligne devient une instance
    • 12. Une colonne devient un attribut
    • 13. Le SQL est désormais une couche de bas niveau
  • 14. Avantages
    • Moins de code pour manipuler les données
    • 15. Plus de code pour écrire l'application
    • 16. Factorisation du problème d'accès aux données
    • 17. Facilités et puissance de l'approche Objet
    • 18. Simplicité d'utilisation
  • 19. Avantages
    • Moins de code pour manipuler les données
    • 20. Plus de code pour écrire l'application
    • 21. Factorisation du problème d'accès aux données
    • 22. Facilités et puissance de l'approche Objet
    • 23. Simplicité d'utilisation
    • 24. Moins de SQL
  • 25. Avantages
    • Moins de code pour manipuler les données
    • 26. Plus de code pour écrire l'application
    • 27. Factorisation du problème d'accès aux données
    • 28. Facilités et puissance de l'approche Objet
    • 29. Simplicité d'utilisation
    • 30. Moins de SQL
    • 31. Moins de SQL
  • 32. Avantages Moins de SQL ??!
  • 33. Avec du SQL ... my $sql = 'select * from table' ; my $sth = $dbh ->prepare( $sql ); $sth ->execute or die $! ; while ( my $row = $sth ->fetchrow_hashref()) { # ici on joue avec $row ... } On a donc 4 lignes pour pouvoir itérer sur des enregistrements...
  • 34. CATS DON'T LIKE SQL
  • 35. Avec Coat::Persistent foreach my $obj (Table->find()) { # ici on joue avec $obj ... } Je crois que le chat s'est calmé...
  • 36. Pourquoi vouloir moins de SQL ?
    • Pour les tâches répétitives, SQL est lourd
    • 37. Chaque fois qu'une requête SQL apparaît dans du code, un risque d'injection est présent
    • 38. La validation des valeurs soumises en SQL est lourde
    • 39. La préparation des valeurs l'est aussi (escaping, conversion de format)
    • 40. Le temps passé à manipuler SQL n'est pas consacré au code métier
  • 41. Mais le SQL est possible
    • On ne ferme pas pour autant la porte au SQL
    • 42. Pour les requêtes complexes, SQL reste un bon choix
    • 43. Pour les requêtes simples et courantes, il faut l'éviter
  • 44. Les ORM en Perl
    • Class::DBI
  • 45. Les ORM en Perl
    • Class::DBI
    • 46. DBIx::Class
  • 47. Les ORM en Perl
  • 50. Les ORM en Perl
  • 55. Les origines de Coat::Persistent
    • ActiveRecord : l'ORM de Ruby on Rails
    • 56. Coat : le mini Moose sans dépendances
    • 57. Deux bonnes idées qui méritaient d'être réunies
  • 58. Objectifs pour Coat::Persistent
    • Simple d'utilisation
  • 59. Objectifs pour Coat::Persistent
    • Simple d'utilisation
    • 60. Léger
  • 61. Objectifs pour Coat::Persistent
  • 64. Objectifs pour Coat::Persistent
    • Simple d'utilisation
    • 65. Léger
    • 66. Rapide
    • 67. Aussi près que possible de l'API ActiveRecord
  • 68. Objectifs pour Coat::Persistent
    • Simple d'utilisation
    • 69. Léger
    • 70. Rapide
    • 71. Aussi près que possible de l'API ActiveRecord
    • 72. Interopérable (MySQL, SQLite, CSV, ...)
  • 73. Mise en place Comment utiliser Coat::Persistent dans votre projet
  • 74. Installation
    • cpan install Coat
    • 75. cpan install Coat::Persistent
    • 76. Le driver DBI pour votre SGBD
  • 77. Une premier modèle C::P package Camel ; use Coat; use Coat::Persistent;
  • 78. Une premier modèle C::P avec MySQL package Camel ; use Coat; use Coat::Persistent; Coat::Persistent->map_to_dbi( mysql => ' dbname ',' dbuser ',' dbpass ');
  • 79. Une premier modèle C::P avec SQLite package Camel ; use Coat; use Coat::Persistent; Coat::Persistent->map_to_dbi( sqlite => ' dbname=dbfile ');
  • 80. Une premier modèle C::P avec CSV package Camel ; use Coat; use Coat::Persistent; Coat::Persistent->map_to_dbi( csv => ' f_dir=dbfile ');
  • 81. Conventions
    • La mapping est possible par défaut ou par classe
    • 82. Le nom de la classe implique un nom de table
    • 83. La clef primaire se nomme « id »
    • 84. Une clef étrangère se nomme table_id
    • 85. On peut surcharger chacune de ces conventions
  • 86. Surcharger les conventions package Camel ; use Coat; use Coat::Persistent table_name => ' camels ', primary_key => ' cid '; Coat::Persistent->map_to_dbi( csv => ' f_dir=dbfile ');
  • 87. Terminer le mapping package Camel ; use Coat; use Coat::Persistent; has_p name => (isa => 'Str'); has_p age => (isa => 'Int'); sqlite> create table camel (id int, name varchar(25), age int);
  • 88. Maintenant il est possible :
    • Remonter des objets à partir de la base
    • 89. Créer de nouvelles entrées
    • 90. Modifier des entrées existantes
    • 91. Accèder au handle de la base de données
    • 92. Obtenir des objets à partir de requetes SQL complexes
  • 93. Coat::Persistent est en place !
  • 94. Un modèle Coat::Persistent
    • C'est une classe qui hérite de Coat::Object
    • 95. C'est une classe qui hérite de Coat::Persistent
    • 96. À ce titre, elle bénéficie de :
      • Méthodes statiques qui s'appliquent à une table
      • 97. Méthodes d'instances qui s'appliquent à une ligne
    • Pour chaque attribut déclaré, des accesseurs et une série de méthodes sont automatiquement définies :
  • 98. Attribut et méthodes La déclaration de l'attribut « foo » implique :
      • $obj->foo()
      • 99. Class->find_by_foo()
      • 100. Class->find_or_create_by_foo()
      • 101. Class->find_or_initialize_by_foo()
  • 102. Création de données
    • Un nouvel objet Coat::Persistent n'est pas sauvé en base tant que save() n'est pas appelé
    • 103. La méthode create() permet de faire un new() et un save()
    • 104. Des méthodes permettent de faire des créations d'objet avec ou sans sauvegarde selon l'existence d'un enregistrement particulier
  • 105. Création de données
    • Class->new() : crée une instance en mémoire
    • 106. $obj->save() : sauve l'instance dans la base de donnée
    • 107. Class->create() : crée et sauve l'instance
    • 108. Class->find_or_create_by_ATTR(val) : find_by_ATTR(val) ou create(ATTR => val)
    • 109. Class->find_or_initialize_by_ATTR(val) : find_by_ATTR(val) ou new(ATTR => val)
  • 110. Exemple de création Perl> my $joe = Camel->new(name =>'joe',age => 7); $Camel1 = Camel=HASH(0x8dcf7a0); Perl> $joe->save 1 sqlite> select * from camel where id = 1; 1|joe|7
  • 111. Exemple de création (plus court) Perl> my $joe = Camel->create(name =>'night',age => 4); $Camel1 = Camel=HASH(0x8dcf7a0); sqlite> select * from camel where id = 1; 1|joe|7 2|night|4
  • 112. Lecture
    • Pour lire les données existantes, on utilise un finder
    • 113. Le contexte d'appel est important (on remonte N entrées avec un contexte de liste et uniquement la première en contexte scalaire)
    • 114. Les finders peuvent se décliner
    • 115. find, find_by_attribut, find(id), find('condition') ...
  • 116. find en contexte de liste Perl> my @camels = Camel->find(); $ARRAY1 = [ Camel=HASH(0x9cfc568), Camel=HASH(0x9cfc718), Camel=HASH(0x9cfc7c8) ];
  • 117. find avec un id Perl> my $camel = Camel->find(1); $Camel1 = Camel=HASH(0x9cfc568)
  • 118. find avec plusieurs id Perl> my @camels = Camel->find(1,2); $ARRAY1 = [ Camel=HASH(0x9ba0648), Camel=HASH(0x9cfc818) ];
  • 119. find avec un attribut Perl> my $joe = Camel->find_by_name('joe'); $Camel1 = Camel=HASH(0x9cfc568) Perl> $joe->name; 'joe'
  • 120. find avec une condition Perl> @camels = Camel->find('age > 10'); $Camel1 = Camel=HASH(0x9d0af78); Perl> $camels[0]->age 12
  • 121. find avec des options Perl> my @camels = Camel->find('age > 3', { order => 'name', limit => '5', });
  • 122. find avec … du SQL Perl> @camels = Camel->find_by_sql('select * from camel where age is not null'); $ARRAY1 = [ Camel=HASH(0x9cfc528), Camel=HASH(0x9cfca78), Camel=HASH(0x94c3380) ];
  • 123. Modifier Perl> $camel = Camel->find(1); $Camel1 = Camel=HASH(0x9cfc528) Perl> $camel->age(3); 3 Perl> $camel->save; 1
  • 124. Supprimer Perl> $camel = Camel->find(1); $Camel1 = Camel=HASH(0x9cfc528) Perl> $camel->delete; 1 Perl> $camel = Camel->find(1); undef
  • 125. N'oublions pas Coat
    • Le hooks de Coat (Moose) s'appliquent très bien ici
    • 126. Chaque méthode proposée par C::P est interceptable via les hooks Coat before, after et around
    • 127. Les méthodes BUILD et DEMOLISH sont implémentables par les objets C::P
    • 128. Types utilisateur et coercition
  • 129. Les hooks
  • 134. Types et Coercition subtype 'DateTime' => as 'Str' => where { /d{4}-dd-dd dd:dd:dd/ }; coerce 'DateTime' => from 'Int' => via { convert_time_to_datetime_str($_) };
  • 135. Types et Coercition has_p 'created_at' => ( is => 'rw', isa => 'DateTime', coerce => 1, ); before 'save' => sub { my ($self) = @_; $self->created_at(time()); };
  • 136. Les relations entre tables
  • 137. Relations côté SQL ... sqlite> create table master (id int, name varchar(25)); sqlite> alter table camel add column master_id int;
  • 138. … et côté Perl package Camel ; use Coat; use Coat::Persistent; has_p name => (isa => 'Str' ); has_p age => (isa => 'Int' ); has_one 'master'; ;
  • 139. … et côté Perl package Master ; use Coat; use Coat::Persistent; has_p name => (isa => 'Str' ); has_many 'camels', class_name => 'Camel'; ;
  • 140. Le maître des chameaux Perl> my $m = Master->create(name => 'Al Kabir') $Master1 = Master=HASH(0x913c168); Perl> my @camels => Camel->find(); $ARRAY1 = [ Camel=HASH(0x913c5e8), Camel=HASH(0x913c588) ]; Perl> map { $_->master($m); $_->save; } @camels;
  • 141. Trouver le maître Perl> my $camel = Camel->find(1); $Camel1 = Camel=HASH(0xa07cd60); Perl> $camel->master $Master1 = Master=HASH(0xa07d050); Perl> $camel->master->name Al Kabir
  • 142. Trouver les chameaux Perl> my $master = Master->find(1); $Master1 = Master=HASH(0xa07d050); Perl> my @camels = $master->camels; $ARRAY1 = [ Camel=HASH(0xa07ce00), Camel=HASH(0xa07d080) ];
  • 143. Accéler les choses
    • Pour améliorer les performances, on peut cacher les résultats des requêtes SQL
    • 144. Le cache est activable à la demande, par Classe ou pour l'ensemble du processus
    • 145. Pour chaque requête SQL générée (pour un set de valeurs données) C::P maintient une entrée en cache avec le résultat
    • 146. Ce résultat en cache est retourné s'il existe
  • 147. Accéler les choses
    • L'expiration des données est gérée en interne par Cache::FastMmap
    • 148. On peut activer/désactiver le cache à la volée
  • 149. Exemple de Cache Pour l'ensemble du processus (toutes les classes C::P sont affectées) Coat::Persistent ->enable_cache( expire_time => '1h' , cache_size => '50m' , share_file => '/var/cache/myapp.cache' , );
  • 150. Exemple de Cache Uniquement pour la classe utilisée Camel ->enable_cache( expire_time => '1h' , cache_size => '50m' , share_file => '/var/cache/myapp.cache' , );
  • 151. Pour la suite ...
    • Gestion de l'option join dans les finder
    • 152. Migrations (classe Coat::Persistent::Migration)
    • 153. Valider de nouveaux drivers DBI
    • 154. Méthodes manquantes de ActiveRecord
    • 155. Optimisations (occupation mémoire, requêtes générées)
  • 156. Pour Contribuer
    • Les patchs sont toujours bienvenus
    • 157. svn co svn://svn.sukria.net:2015/Coat-Persistent
    • 158. Bugs : http://rt.cpan.org
    • 159. Pour me contacter : sukria@sukria.net